diff --git a/configure b/configure index b14eac4b77e..b2f8c33380c 100755 --- a/configure +++ b/configure @@ -509,7 +509,6 @@ opt optimize-tests 1 "build tests with optimizations" opt libcpp 1 "build with llvm with libc++ instead of libstdc++ when using clang" opt llvm-assertions 1 "build LLVM with assertions" opt debug 1 "build with extra debug fun" -opt ratchet-bench 0 "ratchet benchmarks" opt fast-make 0 "use .gitmodules as timestamp for submodule deps" opt ccache 0 "invoke gcc/clang via ccache to reuse object files between builds" opt local-rust 0 "use an installed rustc rather than downloading a snapshot" diff --git a/mk/cfg/aarch64-linux-android.mk b/mk/cfg/aarch64-linux-android.mk new file mode 100644 index 00000000000..a6f7f2ba1d6 --- /dev/null +++ b/mk/cfg/aarch64-linux-android.mk @@ -0,0 +1,30 @@ +# aarch64-linux-android configuration +# CROSS_PREFIX_aarch64-linux-android- +CC_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-gcc +CXX_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-g++ +CPP_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-gcc -E +AR_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-ar +CFG_LIB_NAME_aarch64-linux-android=lib$(1).so +CFG_STATIC_LIB_NAME_aarch64-linux-android=lib$(1).a +CFG_LIB_GLOB_aarch64-linux-android=lib$(1)-*.so +CFG_LIB_DSYM_GLOB_aarch64-linux-android=lib$(1)-*.dylib.dSYM +CFG_JEMALLOC_CFLAGS_aarch64-linux-android := -D__aarch64__ -DANDROID -D__ANDROID__ $(CFLAGS) +CFG_GCCISH_CFLAGS_aarch64-linux-android := -Wall -g -fPIC -D__aarch64__ -DANDROID -D__ANDROID__ $(CFLAGS) +CFG_GCCISH_CXXFLAGS_aarch64-linux-android := -fno-rtti $(CXXFLAGS) +CFG_GCCISH_LINK_FLAGS_aarch64-linux-android := -shared -fPIC -ldl -g -lm -lsupc++ +CFG_GCCISH_DEF_FLAG_aarch64-linux-android := -Wl,--export-dynamic,--dynamic-list= +CFG_GCCISH_PRE_LIB_FLAGS_aarch64-linux-android := -Wl,-whole-archive +CFG_GCCISH_POST_LIB_FLAGS_aarch64-linux-android := -Wl,-no-whole-archive +CFG_DEF_SUFFIX_aarch64-linux-android := .android.def +CFG_LLC_FLAGS_aarch64-linux-android := +CFG_INSTALL_NAME_aarch64-linux-android = +CFG_EXE_SUFFIX_aarch64-linux-android := +CFG_WINDOWSY_aarch64-linux-android := +CFG_UNIXY_aarch64-linux-android := 1 +CFG_PATH_MUNGE_aarch64-linux-android := true +CFG_LDPATH_aarch64-linux-android := +CFG_RUN_aarch64-linux-android= +CFG_RUN_TARG_aarch64-linux-android= +RUSTC_FLAGS_aarch64-linux-android := +RUSTC_CROSS_FLAGS_aarch64-linux-android := +CFG_GNU_TRIPLE_aarch64-linux-android := aarch64-linux-android diff --git a/mk/rt.mk b/mk/rt.mk index 6a7be26c7a6..a8bbeb41517 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -141,6 +141,8 @@ else ifeq ($(OSTYPE_$(1)), apple-ios) JEMALLOC_ARGS_$(1) := --disable-tls else ifeq ($(OSTYPE_$(1)), linux-androideabi) JEMALLOC_ARGS_$(1) := --disable-tls +else ifeq ($(OSTYPE_$(1)), linux-android) + JEMALLOC_ARGS_$(1) := --disable-tls endif ################################################################################ diff --git a/mk/tests.mk b/mk/tests.mk index 02cc745803f..32d4d178e6b 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -300,6 +300,7 @@ tidy: | grep '^$(S)src/libbacktrace' -v \ | grep '^$(S)src/rust-installer' -v \ | xargs $(CFG_PYTHON) $(S)src/etc/check-binaries.py + $(Q) $(CFG_PYTHON) $(S)src/etc/errorck.py $(S)src/ endif diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index c29f74d7418..c21785c45a3 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -13,7 +13,7 @@ use std::str::FromStr; use regex::Regex; -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Debug)] pub enum Mode { CompileFail, RunFail, @@ -43,9 +43,9 @@ fn from_str(s: &str) -> Option { } } -impl fmt::String for Mode { +impl fmt::Display for Mode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::String::fmt(match *self { + fmt::Display::fmt(match *self { CompileFail => "compile-fail", RunFail => "run-fail", RunPass => "run-pass", @@ -58,12 +58,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::Show for Mode { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::String::fmt(self, f) - } -} - #[derive(Clone)] pub struct Config { // The library paths required for running the compiler @@ -115,20 +109,6 @@ pub struct Config { // Write out a parseable log of tests that were run pub logfile: Option, - // Write out a json file containing any metrics of the run - pub save_metrics: Option, - - // Write and ratchet a metrics file - pub ratchet_metrics: Option, - - // Percent change in metrics to consider noise - pub ratchet_noise_percent: Option, - - // "Shard" of the testsuite to pub run: this has the form of - // two numbers (a,b), and causes only those tests with - // positional order equal to a mod b to run. - pub test_shard: Option<(uint,uint)>, - // A command line to prefix program execution with, // for running under valgrind pub runtool: Option, diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index f3514c6e7bc..1a9a1c08b07 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -77,10 +77,6 @@ pub fn parse_config(args: Vec ) -> Config { optopt("", "target-rustcflags", "flags to pass to rustc for target", "FLAGS"), optflag("", "verbose", "run tests verbosely, showing all output"), optopt("", "logfile", "file to log test execution to", "FILE"), - optopt("", "save-metrics", "file to save metrics to", "FILE"), - optopt("", "ratchet-metrics", "file to ratchet metrics against", "FILE"), - optopt("", "ratchet-noise-percent", - "percent change in metrics to consider noise", "N"), optflag("", "jit", "run tests under the JIT"), optopt("", "target", "the target to build for", "TARGET"), optopt("", "host", "the host to build for", "HOST"), @@ -90,7 +86,6 @@ pub fn parse_config(args: Vec ) -> Config { optopt("", "adb-path", "path to the android debugger", "PATH"), optopt("", "adb-test-dir", "path to tests for the android debugger", "PATH"), optopt("", "lldb-python-dir", "directory containing LLDB's python module", "PATH"), - optopt("", "test-shard", "run shard A, of B shards, worth of the testsuite", "A.B"), optflag("h", "help", "show this message")); assert!(!args.is_empty()); @@ -152,12 +147,6 @@ fn opt_path(m: &getopts::Matches, nm: &str) -> Path { filter: filter, cfail_regex: Regex::new(errors::EXPECTED_PATTERN).unwrap(), logfile: matches.opt_str("logfile").map(|s| Path::new(s)), - save_metrics: matches.opt_str("save-metrics").map(|s| Path::new(s)), - ratchet_metrics: - matches.opt_str("ratchet-metrics").map(|s| Path::new(s)), - ratchet_noise_percent: - matches.opt_str("ratchet-noise-percent") - .and_then(|s| s.as_slice().parse::()), runtool: matches.opt_str("runtool"), host_rustcflags: matches.opt_str("host-rustcflags"), target_rustcflags: matches.opt_str("target-rustcflags"), @@ -176,7 +165,6 @@ fn opt_path(m: &getopts::Matches, nm: &str) -> Path { opt_str2(matches.opt_str("adb-test-dir")).as_slice() && !opt_str2(matches.opt_str("adb-test-dir")).is_empty(), lldb_python_dir: matches.opt_str("lldb-python-dir"), - test_shard: test::opt_shard(matches.opt_str("test-shard")), verbose: matches.opt_present("verbose"), } } @@ -210,10 +198,6 @@ pub fn log_config(config: &Config) { logv(c, format!("adb_test_dir: {:?}", config.adb_test_dir)); logv(c, format!("adb_device_status: {}", config.adb_device_status)); - match config.test_shard { - None => logv(c, "test_shard: (all)".to_string()), - Some((a,b)) => logv(c, format!("test_shard: {}.{}", a, b)) - } logv(c, format!("verbose: {}", config.verbose)); logv(c, format!("\n")); } @@ -284,15 +268,8 @@ pub fn test_opts(config: &Config) -> test::TestOpts { logfile: config.logfile.clone(), run_tests: true, run_benchmarks: true, - ratchet_metrics: config.ratchet_metrics.clone(), - ratchet_noise_percent: config.ratchet_noise_percent.clone(), - save_metrics: config.save_metrics.clone(), - test_shard: config.test_shard.clone(), nocapture: false, color: test::AutoColor, - show_boxplot: false, - boxplot_width: 50, - show_all_stats: false, } } diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index 2413a001ee8..d7af767688e 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -332,8 +332,7 @@ pub fn parse_name_value_directive(line: &str, directive: &str) let keycolon = format!("{}:", directive); match line.find_str(keycolon.as_slice()) { Some(colon) => { - let value = line.slice(colon + keycolon.len(), - line.len()).to_string(); + let value = line[(colon + keycolon.len()) .. line.len()].to_string(); debug!("{}: {}", directive, value); Some(value) } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 5579479c5e5..f075cff769f 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -294,6 +294,7 @@ fn make_pp_args(config: &Config, let aux_dir = aux_output_dir_name(config, testfile); // FIXME (#9639): This needs to handle non-utf8 paths let mut args = vec!("-".to_string(), + "-Zunstable-options".to_string(), "--pretty".to_string(), pretty_type, format!("--target={}", config.target), @@ -340,7 +341,7 @@ fn make_typecheck_args(config: &Config, props: &TestProps, testfile: &Path) -> P }; // FIXME (#9639): This needs to handle non-utf8 paths let mut args = vec!("-".to_string(), - "--no-trans".to_string(), + "-Zno-trans".to_string(), "--crate-type=lib".to_string(), format!("--target={}", target), "-L".to_string(), @@ -547,7 +548,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { // Add line breakpoints for line in breakpoint_lines.iter() { - script_str.push_str(&format!("break '{:?}':{}\n", + script_str.push_str(&format!("break '{}':{}\n", testfile.filename_display(), *line)[]); } @@ -750,7 +751,7 @@ fn run_lldb(config: &Config, status: status, stdout: out, stderr: err, - cmdline: format!("{}", cmd) + cmdline: format!("{:?}", cmd) }; } } @@ -862,7 +863,7 @@ fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[String]) break; } Some(i) => { - rest = rest.slice_from(i + frag.len()); + rest = &rest[(i + frag.len())..]; } } first = false; @@ -953,7 +954,7 @@ fn check_expected_errors(expected_errors: Vec , } let prefixes = expected_errors.iter().map(|ee| { - format!("{:?}:{}:", testfile.display(), ee.line) + format!("{}:{}:", testfile.display(), ee.line) }).collect:: >(); #[cfg(windows)] @@ -1045,7 +1046,7 @@ fn scan_until_char(haystack: &str, needle: char, idx: &mut uint) -> bool { if *idx >= haystack.len() { return false; } - let opt = haystack.slice_from(*idx).find(needle); + let opt = haystack[(*idx)..].find(needle); if opt.is_none() { return false; } diff --git a/src/doc/intro.md b/src/doc/intro.md index 3487738467f..b92d38215c2 100644 --- a/src/doc/intro.md +++ b/src/doc/intro.md @@ -480,14 +480,12 @@ use std::sync::{Arc,Mutex}; fn main() { let numbers = Arc::new(Mutex::new(vec![1is, 2, 3])); - for i in 0..3 { + for i in 0us..3 { let number = numbers.clone(); Thread::spawn(move || { let mut array = number.lock().unwrap(); - - (*array)[i] += 1; - - println!("numbers[{}] is {}", i, (*array)[i]); + array[i] += 1; + println!("numbers[{}] is {}", i, array[i]); }); } } diff --git a/src/doc/reference.md b/src/doc/reference.md index d3af4ab1c74..9ec4708eb2f 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -803,8 +803,9 @@ Crates contain [items](#items), each of which may have some number of ## Items ```{.ebnf .gram} -item : mod_item | fn_item | type_item | struct_item | enum_item - | static_item | trait_item | impl_item | extern_block ; +item : extern_crate_decl | use_decl | mod_item | fn_item | type_item + | struct_item | enum_item | static_item | trait_item | impl_item + | extern_block ; ``` An _item_ is a component of a crate; some module items can be defined in crate @@ -818,6 +819,8 @@ execution, and may reside in read-only memory. There are several kinds of item: +* [`extern crate` declarations](#extern-crate-declarations) +* [`use` declarations](#use-declarations) * [modules](#modules) * [functions](#functions) * [type definitions](#type-definitions) @@ -854,13 +857,10 @@ no notion of type abstraction: there are no first-class "forall" types. ```{.ebnf .gram} mod_item : "mod" ident ( ';' | '{' mod '}' ); -mod : [ view_item | item ] * ; +mod : item * ; ``` -A module is a container for zero or more [view items](#view-items) and zero or -more [items](#items). The view items manage the visibility of the items defined -within the module, as well as the visibility of names from outside the module -when referenced from inside the module. +A module is a container for zero or more [items](#items). A _module item_ is a module, surrounded in braces, named, and prefixed with the keyword `mod`. A module item introduces a new, named module into the tree of @@ -918,19 +918,6 @@ mod thread { } ``` -#### View items - -```{.ebnf .gram} -view_item : extern_crate_decl | use_decl ; -``` - -A view item manages the namespace of a module. View items do not define new -items, but rather, simply change other items' visibility. There are two -kinds of view items: - -* [`extern crate` declarations](#extern-crate-declarations) -* [`use` declarations](#use-declarations) - ##### Extern crate declarations ```{.ebnf .gram} @@ -2377,10 +2364,6 @@ These types help drive the compiler's analysis : ___Needs filling in___ * `no_copy_bound` : This type does not implement "copy", even if eligible. -* `no_send_bound` - : This type does not implement "send", even if eligible. -* `no_sync_bound` - : This type does not implement "sync", even if eligible. * `eh_personality` : ___Needs filling in___ * `exchange_free` @@ -2891,13 +2874,12 @@ Point3d {y: 0, z: 10, .. base}; ### Block expressions ```{.ebnf .gram} -block_expr : '{' [ view_item ] * - [ stmt ';' | item ] * +block_expr : '{' [ stmt ';' | item ] * [ expr ] '}' ; ``` A _block expression_ is similar to a module in terms of the declarations that -are possible. Each block conceptually introduces a new namespace scope. View +are possible. Each block conceptually introduces a new namespace scope. Use items can bring new names into scopes and declared items are in scope for only the block itself. diff --git a/src/doc/trpl/crates-and-modules.md b/src/doc/trpl/crates-and-modules.md index 25870d84a75..79bb5c182f4 100644 --- a/src/doc/trpl/crates-and-modules.md +++ b/src/doc/trpl/crates-and-modules.md @@ -257,7 +257,7 @@ fn goodbye() -> String { (This is "Sayōnara", if you're curious.) -Now that we have our some functionality in our crate, let's try to use it from +Now that we have some functionality in our crate, let's try to use it from another crate. # Importing External Crates diff --git a/src/doc/trpl/if.md b/src/doc/trpl/if.md index ea1da167458..a350df67b17 100644 --- a/src/doc/trpl/if.md +++ b/src/doc/trpl/if.md @@ -1,4 +1,4 @@ -% `if` +% If Rust's take on `if` is not particularly complex, but it's much more like the `if` you'll find in a dynamically typed language than in a more traditional diff --git a/src/doc/trpl/looping.md b/src/doc/trpl/looping.md index 28f02b1ffe1..4301149d1f8 100644 --- a/src/doc/trpl/looping.md +++ b/src/doc/trpl/looping.md @@ -123,7 +123,7 @@ We now loop forever with `loop` and use `break` to break out early. iteration. This will only print the odd numbers: ```{rust} -for x in 0..10 { +for x in 0u32..10 { if x % 2 == 0 { continue; } println!("{}", x); diff --git a/src/doc/trpl/threads.md b/src/doc/trpl/threads.md index 1bad09b4b6e..a801a1ab0e9 100644 --- a/src/doc/trpl/threads.md +++ b/src/doc/trpl/threads.md @@ -179,7 +179,7 @@ for init_val in 0 .. 3 { } let result = rx.recv().unwrap() + rx.recv().unwrap() + rx.recv().unwrap(); -# fn some_expensive_computation(_i: u32) -> u32 { 42 } +# fn some_expensive_computation(_i: i32) -> i32 { 42 } ``` Cloning a `Sender` produces a new handle to the same channel, allowing multiple @@ -207,7 +207,7 @@ let rxs = (0 .. 3).map(|&:init_val| { // Wait on each port, accumulating the results let result = rxs.iter().fold(0, |&:accum, rx| accum + rx.recv().unwrap() ); -# fn some_expensive_computation(_i: u32) -> u32 { 42 } +# fn some_expensive_computation(_i: i32) -> i32 { 42 } ``` ## Backgrounding computations: Futures diff --git a/src/doc/trpl/unsafe.md b/src/doc/trpl/unsafe.md index 2a66b4a01f7..3acd1eefe89 100644 --- a/src/doc/trpl/unsafe.md +++ b/src/doc/trpl/unsafe.md @@ -707,7 +707,7 @@ Other features provided by lang items include: various kinds; lang items `send`, `sync` and `copy`. - the marker types and variance indicators found in `std::marker`; lang items `covariant_type`, - `contravariant_lifetime`, `no_sync_bound`, etc. + `contravariant_lifetime`, etc. Lang items are loaded lazily by the compiler; e.g. if one never uses `Box` then there is no need to define functions for `exchange_malloc` diff --git a/src/etc/emacs/rust-mode.el b/src/etc/emacs/rust-mode.el index f25a59015fc..dae685f3a54 100644 --- a/src/etc/emacs/rust-mode.el +++ b/src/etc/emacs/rust-mode.el @@ -54,6 +54,11 @@ :type 'integer :group 'rust-mode) +(defcustom rust-indent-method-chain nil + "Indent Rust method chains, aligned by the '.' operators" + :type 'boolean + :group 'rust-mode) + (defun rust-paren-level () (nth 0 (syntax-ppss))) (defun rust-in-str-or-cmnt () (nth 8 (syntax-ppss))) (defun rust-rewind-past-str-cmnt () (goto-char (nth 8 (syntax-ppss)))) @@ -73,10 +78,19 @@ ;; open bracket ends the line (when (not (looking-at "[[:blank:]]*\\(?://.*\\)?$")) (when (looking-at "[[:space:]]") - (forward-word 1) - (backward-word 1)) + (forward-word 1) + (backward-word 1)) (current-column)))) +(defun rust-align-to-method-chain () + (save-excursion + (previous-line) + (end-of-line) + (backward-word 1) + (backward-char) + (when (looking-at "\\..+\(.*\)\n") + (- (current-column) rust-indent-offset)))) + (defun rust-rewind-to-beginning-of-current-level-expr () (let ((current-level (rust-paren-level))) (back-to-indentation) @@ -99,10 +113,13 @@ ;; the inside of it correctly relative to the outside. (if (= 0 level) 0 + (or + (when rust-indent-method-chain + (rust-align-to-method-chain)) (save-excursion (backward-up-list) (rust-rewind-to-beginning-of-current-level-expr) - (+ (current-column) rust-indent-offset))))) + (+ (current-column) rust-indent-offset)))))) (cond ;; A function return type is indented to the corresponding function arguments ((looking-at "->") @@ -114,6 +131,16 @@ ;; A closing brace is 1 level unindended ((looking-at "}") (- baseline rust-indent-offset)) + ;;Line up method chains by their .'s + ((when (and rust-indent-method-chain + (looking-at "\..+\(.*\);?\n")) + (or + (let ((method-indent (rust-align-to-method-chain))) + (when method-indent + (+ method-indent rust-indent-offset))) + (+ baseline rust-indent-offset)))) + + ;; Doc comments in /** style with leading * indent to line up the *s ((and (nth 4 (syntax-ppss)) (looking-at "*")) (+ 1 baseline)) diff --git a/src/etc/errorck.py b/src/etc/errorck.py new file mode 100644 index 00000000000..17659309d3b --- /dev/null +++ b/src/etc/errorck.py @@ -0,0 +1,70 @@ +# 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 or the MIT license +# , at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +# Digs error codes out of files named 'diagnostics.rs' across +# the tree, and ensures thare are no duplicates. + +import sys, os, re + +src_dir = sys.argv[1] + +errcode_map = { } + +for (dirpath, dirnames, filenames) in os.walk(src_dir): + + if "src/test" in dirpath or "src/llvm" in dirpath: + # Short circuit for fast + continue + + for filename in filenames: + if filename != "diagnostics.rs": + continue + + path = os.path.join(dirpath, filename) + line_num = 1 + with open(path, 'r') as f: + for line in f: + + p = re.compile("(E\d\d\d\d)") + m = p.search(line) + if not m is None: + errcode = m.group(1) + + new_record = [(errcode, path, line_num, line)] + existing = errcode_map.get(errcode) + if existing is not None: + # This is a dupe + errcode_map[errcode] = existing + new_record + else: + errcode_map[errcode] = new_record + + line_num += 1 + +errors = False +all_errors = [] +for errcode in errcode_map: + entries = errcode_map[errcode] + all_errors += [entries[0][0]] + if len(entries) > 1: + print "error: duplicate error code " + errcode + for entry in entries: + print entry[1] + ": " + str(entry[2]) + print entry[3] + errors = True + +print str(len(errcode_map)) + " error codes" + +all_errors.sort() +all_errors.reverse() + +print "highest error code: " + all_errors[0] + +if errors: + sys.exit(1) diff --git a/src/etc/rustup.sh b/src/etc/rustup.sh index 749d9eaa173..07e832d317a 100755 --- a/src/etc/rustup.sh +++ b/src/etc/rustup.sh @@ -433,11 +433,16 @@ CFG_TMP_DIR=$(mktemp -d 2>/dev/null \ || mktemp -d -t 'rustup-tmp-install' 2>/dev/null \ || create_tmp_dir) -# If we're saving nightlies and we didn't specify which one, grab todays. -# Otherwise we'll use the latest version. +# If we're saving nightlies and we didn't specify which one, grab the latest +# verison from the perspective of the server. Buildbot has typically finished +# building and uploading by ~8UTC, but we want to include a little buffer. +# +# FIXME It would be better to use the known most recent nightly that has been +# built. This is waiting on a change to have buildbot publish metadata that +# can be queried. if [ -n "${CFG_SAVE}" -a -z "${CFG_DATE}" ]; then - CFG_DATE=`date "+%Y-%m-%d"` + CFG_DATE=`TZ=Etc/UTC+9 date "+%Y-%m-%d"` fi RUST_URL="https://static.rust-lang.org/dist" @@ -453,16 +458,33 @@ then RUST_URL="${RUST_URL}/${CFG_DATE}" fi -verify_hash() { - remote_sha256="$1" - local_file="$2" - +download_hash() { msg "Downloading ${remote_sha256}" remote_sha256=`"${CFG_CURL}" -f "${remote_sha256}"` + if [ -n "${CFG_SAVE}" ]; then + echo "${remote_sha256}" > "${local_sha_file}" + fi if [ "$?" -ne 0 ]; then rm -Rf "${CFG_TMP_DIR}" err "Failed to download ${remote_url}" fi +} + +verify_hash() { + remote_sha256="$1" + local_file="$2" + local_sha_file="${local_file}.sha256" + + if [ -n "${CFG_SAVE}" ]; then + if [ -f "${local_sha_file}" ]; then + msg "Local ${local_sha_file} exists, treating as remote hash" + remote_sha256=`cat "${local_sha_file}"` + else + download_hash + fi + else + download_hash + fi msg "Verifying hash" local_sha256=$(calculate_hash "${local_file}") diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index c0cd034abfa..5f8cd6baf9a 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -72,7 +72,7 @@ use core::atomic; use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst}; use core::borrow::BorrowFrom; -use core::fmt::{self, Show}; +use core::fmt; use core::cmp::{Ordering}; use core::default::Default; use core::mem::{min_align_of, size_of}; @@ -578,16 +578,17 @@ fn cmp(&self, other: &Arc) -> Ordering { (**self).cmp(&**other) } #[stable] impl Eq for Arc {} -impl fmt::Show for Arc { +#[stable] +impl fmt::Display for Arc { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Arc({:?})", (**self)) + fmt::Display::fmt(&**self, f) } } #[stable] -impl fmt::String for Arc { +impl fmt::Debug for Arc { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::String::fmt(&**self, f) + fmt::Debug::fmt(&**self, f) } } @@ -806,7 +807,7 @@ fn test_weak_count() { #[test] fn show_arc() { let a = Arc::new(5u32); - assert!(format!("{:?}", a) == "Arc(5u32)") + assert_eq!(format!("{:?}", a), "5"); } // Make sure deriving works with Arc diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index a2cc98c7d01..5ec08a1f254 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -16,16 +16,18 @@ use core::clone::Clone; use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering}; use core::default::Default; +use core::error::{Error, FromError}; use core::fmt; use core::hash::{self, Hash}; +use core::iter::Iterator; use core::marker::Sized; use core::mem; +use core::ops::{Deref, DerefMut}; use core::option::Option; use core::ptr::Unique; use core::raw::TraitObject; -use core::result::Result; use core::result::Result::{Ok, Err}; -use core::ops::{Deref, DerefMut}; +use core::result::Result; /// A value that represents the global exchange heap. This is the default /// place that the `box` keyword allocates into when no place is supplied. @@ -156,20 +158,22 @@ fn downcast(self) -> Result, Box> { } } -impl fmt::Show for Box { +#[stable] +impl fmt::Display for Box { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Box({:?})", &**self) + fmt::Display::fmt(&**self, f) } } #[stable] -impl fmt::String for Box { +impl fmt::Debug for Box { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::String::fmt(&**self, f) + fmt::Debug::fmt(&**self, f) } } -impl fmt::Show for Box { +#[stable] +impl fmt::Debug for Box { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.pad("Box") } @@ -187,56 +191,22 @@ impl DerefMut for Box { fn deref_mut(&mut self) -> &mut T { &mut **self } } -#[cfg(test)] -mod test { - #[test] - fn test_owned_clone() { - let a = Box::new(5i); - let b: Box = a.clone(); - assert!(a == b); +// FIXME(#21363) remove `old_impl_check` when bug is fixed +#[old_impl_check] +impl<'a, T> Iterator for Box + 'a> { + type Item = T; + + fn next(&mut self) -> Option { + (**self).next() } - #[test] - fn any_move() { - let a = Box::new(8u) as Box; - let b = Box::new(Test) as Box; - - match a.downcast::() { - Ok(a) => { assert!(a == Box::new(8u)); } - Err(..) => panic!() - } - match b.downcast::() { - Ok(a) => { assert!(a == Box::new(Test)); } - Err(..) => panic!() - } - - let a = Box::new(8u) as Box; - let b = Box::new(Test) as Box; - - assert!(a.downcast::>().is_err()); - assert!(b.downcast::>().is_err()); - } - - #[test] - fn test_show() { - let a = Box::new(8u) as Box; - let b = Box::new(Test) as Box; - let a_str = a.to_str(); - let b_str = b.to_str(); - assert_eq!(a_str, "Box"); - assert_eq!(b_str, "Box"); - - let a = &8u as &Any; - let b = &Test as &Any; - let s = format!("{}", a); - assert_eq!(s, "&Any"); - let s = format!("{}", b); - assert_eq!(s, "&Any"); - } - - #[test] - fn deref() { - fn homura>(_: T) { } - homura(Box::new(765i32)); + fn size_hint(&self) -> (usize, Option) { + (**self).size_hint() + } +} + +impl<'a, E: Error + 'a> FromError for Box { + fn from_error(err: E) -> Box { + Box::new(err) } } diff --git a/src/liballoc/boxed_test.rs b/src/liballoc/boxed_test.rs new file mode 100644 index 00000000000..c47a771f60d --- /dev/null +++ b/src/liballoc/boxed_test.rs @@ -0,0 +1,75 @@ +// 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. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Test for `boxed` mod. + +use core::any::Any; +use core::ops::Deref; +use core::result::Result::{Ok, Err}; +use core::clone::Clone; + +use std::boxed::Box; +use std::boxed::BoxAny; + +#[test] +fn test_owned_clone() { + let a = Box::new(5i); + let b: Box = a.clone(); + assert!(a == b); +} + +#[derive(PartialEq, Eq)] +struct Test; + +#[test] +fn any_move() { + let a = Box::new(8u) as Box; + let b = Box::new(Test) as Box; + + match a.downcast::() { + Ok(a) => { assert!(a == Box::new(8u)); } + Err(..) => panic!() + } + match b.downcast::() { + Ok(a) => { assert!(a == Box::new(Test)); } + Err(..) => panic!() + } + + let a = Box::new(8u) as Box; + let b = Box::new(Test) as Box; + + assert!(a.downcast::>().is_err()); + assert!(b.downcast::>().is_err()); +} + +#[test] +fn test_show() { + let a = Box::new(8u) as Box; + let b = Box::new(Test) as Box; + let a_str = format!("{:?}", a); + let b_str = format!("{:?}", b); + assert_eq!(a_str, "Box"); + assert_eq!(b_str, "Box"); + + static EIGHT: usize = 8us; + static TEST: Test = Test; + let a = &EIGHT as &Any; + let b = &TEST as &Any; + let s = format!("{:?}", a); + assert_eq!(s, "&Any"); + let s = format!("{:?}", b); + assert_eq!(s, "&Any"); +} + +#[test] +fn deref() { + fn homura>(_: T) { } + homura(Box::new(765i32)); +} diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index bd5b43b782e..a2643f4d0f7 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -280,7 +280,7 @@ pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 { if align <= MIN_ALIGN { libc::malloc(size as libc::size_t) as *mut u8 } else { - let mut out = 0 as *mut libc::c_void; + let mut out = ptr::null_mut(); let ret = posix_memalign(&mut out, align as libc::size_t, size as libc::size_t); diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 811e32e747d..231ef6e7e74 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -70,6 +70,8 @@ #![feature(lang_items, unsafe_destructor)] #![feature(box_syntax)] #![feature(optin_builtin_traits)] +// FIXME(#21363) remove `old_impl_check` when bug is fixed +#![feature(old_impl_check)] #![allow(unknown_features)] #![feature(int_uint)] #[macro_use] @@ -91,6 +93,8 @@ #[cfg(not(test))] pub mod boxed; +#[cfg(test)] +mod boxed_test; pub mod arc; pub mod rc; diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 7191a7af346..5e82c4f1ade 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -174,61 +174,17 @@ struct RcBox { /// See the [module level documentation](../index.html) for more details. #[unsafe_no_drop_flag] #[stable] -#[cfg(stage0)] // NOTE remove impl after next snapshot -pub struct Rc { - // FIXME #12808: strange names to try to avoid interfering with field accesses of the contained - // type via Deref - _ptr: NonZero<*mut RcBox>, - _nosend: marker::NoSend, - _noshare: marker::NoSync -} - -/// An immutable reference-counted pointer type. -/// -/// See the [module level documentation](../index.html) for more details. -#[unsafe_no_drop_flag] -#[stable] -#[cfg(not(stage0))] // NOTE remove cfg after next snapshot pub struct Rc { // FIXME #12808: strange names to try to avoid interfering with field accesses of the contained // type via Deref _ptr: NonZero<*mut RcBox>, } -#[cfg(not(stage0))] // NOTE remove cfg after next snapshot impl !marker::Send for Rc {} -#[cfg(not(stage0))] // NOTE remove cfg after next snapshot impl !marker::Sync for Rc {} impl Rc { - /// Constructs a new `Rc`. - /// - /// # Examples - /// - /// ``` - /// use std::rc::Rc; - /// - /// let five = Rc::new(5i); - /// ``` - #[stable] - #[cfg(stage0)] // NOTE remove after next snapshot - pub fn new(value: T) -> Rc { - unsafe { - Rc { - // there is an implicit weak pointer owned by all the strong pointers, which - // ensures that the weak destructor never frees the allocation while the strong - // destructor is running, even if the weak pointer is stored inside the strong one. - _ptr: NonZero::new(transmute(box RcBox { - value: value, - strong: Cell::new(1), - weak: Cell::new(1) - })), - _nosend: marker::NoSend, - _noshare: marker::NoSync - } - } - } /// Constructs a new `Rc`. /// @@ -240,7 +196,6 @@ pub fn new(value: T) -> Rc { /// let five = Rc::new(5i); /// ``` #[stable] - #[cfg(not(stage0))] // NOTE remove cfg after next snapshot pub fn new(value: T) -> Rc { unsafe { Rc { @@ -267,29 +222,6 @@ pub fn new(value: T) -> Rc { /// /// let weak_five = five.downgrade(); /// ``` - #[cfg(stage0)] // NOTE remove after next snapshot - #[unstable = "Weak pointers may not belong in this module"] - pub fn downgrade(&self) -> Weak { - self.inc_weak(); - Weak { - _ptr: self._ptr, - _nosend: marker::NoSend, - _noshare: marker::NoSync - } - } - - /// Downgrades the `Rc` to a `Weak` reference. - /// - /// # Examples - /// - /// ``` - /// use std::rc::Rc; - /// - /// let five = Rc::new(5i); - /// - /// let weak_five = five.downgrade(); - /// ``` - #[cfg(not(stage0))] // NOTE remove cfg after next snapshot #[unstable = "Weak pointers may not belong in this module"] pub fn downgrade(&self) -> Weak { self.inc_weak(); @@ -483,25 +415,6 @@ fn drop(&mut self) { #[stable] impl Clone for Rc { - /// Makes a clone of the `Rc`. - /// - /// This increases the strong reference count. - /// - /// # Examples - /// - /// ``` - /// use std::rc::Rc; - /// - /// let five = Rc::new(5i); - /// - /// five.clone(); - /// ``` - #[inline] - #[cfg(stage0)] // NOTE remove after next snapshot - fn clone(&self) -> Rc { - self.inc_strong(); - Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync } - } /// Makes a clone of the `Rc`. /// @@ -517,7 +430,6 @@ fn clone(&self) -> Rc { /// five.clone(); /// ``` #[inline] - #[cfg(not(stage0))] // NOTE remove cfg after next snapshot fn clone(&self) -> Rc { self.inc_strong(); Rc { _ptr: self._ptr } @@ -693,17 +605,17 @@ fn hash(&self, state: &mut S) { } } -#[unstable = "Show is experimental."] -impl fmt::Show for Rc { +#[stable] +impl fmt::Display for Rc { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Rc({:?})", **self) + fmt::Display::fmt(&**self, f) } } #[stable] -impl fmt::String for Rc { +impl fmt::Debug for Rc { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::String::fmt(&**self, f) + fmt::Debug::fmt(&**self, f) } } @@ -714,66 +626,21 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { /// See the [module level documentation](../index.html) for more. #[unsafe_no_drop_flag] #[unstable = "Weak pointers may not belong in this module."] -#[cfg(stage0)] // NOTE remove impl after next snapshot -pub struct Weak { - // FIXME #12808: strange names to try to avoid interfering with - // field accesses of the contained type via Deref - _ptr: NonZero<*mut RcBox>, - _nosend: marker::NoSend, - _noshare: marker::NoSync -} - -/// A weak version of `Rc`. -/// -/// Weak references do not count when determining if the inner value should be dropped. -/// -/// See the [module level documentation](../index.html) for more. -#[unsafe_no_drop_flag] -#[unstable = "Weak pointers may not belong in this module."] -#[cfg(not(stage0))] // NOTE remove cfg after next snapshot pub struct Weak { // FIXME #12808: strange names to try to avoid interfering with // field accesses of the contained type via Deref _ptr: NonZero<*mut RcBox>, } -#[cfg(not(stage0))] // NOTE remove cfg after next snapshot #[allow(unstable)] impl !marker::Send for Weak {} -#[cfg(not(stage0))] // NOTE remove cfg after next snapshot #[allow(unstable)] impl !marker::Sync for Weak {} #[unstable = "Weak pointers may not belong in this module."] impl Weak { - /// Upgrades a weak reference to a strong reference. - /// - /// Upgrades the `Weak` reference to an `Rc`, if possible. - /// - /// Returns `None` if there were no strong references and the data was destroyed. - /// - /// # Examples - /// - /// ``` - /// use std::rc::Rc; - /// - /// let five = Rc::new(5i); - /// - /// let weak_five = five.downgrade(); - /// - /// let strong_five: Option> = weak_five.upgrade(); - /// ``` - #[cfg(stage0)] // NOTE remove after next snapshot - pub fn upgrade(&self) -> Option> { - if self.strong() == 0 { - None - } else { - self.inc_strong(); - Some(Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync }) - } - } /// Upgrades a weak reference to a strong reference. /// @@ -792,7 +659,6 @@ pub fn upgrade(&self) -> Option> { /// /// let strong_five: Option> = weak_five.upgrade(); /// ``` - #[cfg(not(stage0))] // NOTE remove cfg after next snapshot pub fn upgrade(&self) -> Option> { if self.strong() == 0 { None @@ -849,25 +715,6 @@ fn drop(&mut self) { #[unstable = "Weak pointers may not belong in this module."] impl Clone for Weak { - /// Makes a clone of the `Weak`. - /// - /// This increases the weak reference count. - /// - /// # Examples - /// - /// ``` - /// use std::rc::Rc; - /// - /// let weak_five = Rc::new(5i).downgrade(); - /// - /// weak_five.clone(); - /// ``` - #[inline] - #[cfg(stage0)] // NOTE remove after next snapshot - fn clone(&self) -> Weak { - self.inc_weak(); - Weak { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync } - } /// Makes a clone of the `Weak`. /// @@ -883,15 +730,14 @@ fn clone(&self) -> Weak { /// weak_five.clone(); /// ``` #[inline] - #[cfg(not(stage0))] // NOTE remove cfg after next snapshot fn clone(&self) -> Weak { self.inc_weak(); Weak { _ptr: self._ptr } } } -#[unstable = "Show is experimental."] -impl fmt::Show for Weak { +#[stable] +impl fmt::Debug for Weak { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "(Weak)") } @@ -1134,7 +980,7 @@ fn test_cowrc_clone_weak() { #[test] fn test_show() { let foo = Rc::new(75u); - assert!(format!("{:?}", foo) == "Rc(75u)") + assert_eq!(format!("{:?}", foo), "75"); } } diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index efd056b0d66..4c07f5b31e6 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -330,7 +330,7 @@ pub fn from_bytes(bytes: &[u8]) -> Bitv { if extra_bytes > 0 { let mut last_word = 0u32; - for (i, &byte) in bytes[(complete_words*4)..].iter().enumerate() { + for (i, &byte) in bytes[complete_words*4..].iter().enumerate() { last_word |= (reverse_bits(byte) as u32) << (i * 8); } bitv.storage.push(last_word); @@ -972,7 +972,7 @@ fn cmp(&self, other: &Bitv) -> Ordering { } #[stable] -impl fmt::Show for Bitv { +impl fmt::Debug for Bitv { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { for bit in self.iter() { try!(write!(fmt, "{}", if bit { 1u32 } else { 0u32 })); @@ -1727,7 +1727,7 @@ pub fn remove(&mut self, value: &uint) -> bool { } } -impl fmt::Show for BitvSet { +impl fmt::Debug for BitvSet { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { try!(write!(fmt, "BitvSet {{")); let mut first = true; @@ -2622,7 +2622,7 @@ fn test_bitv_set_show() { s.insert(10); s.insert(50); s.insert(2); - assert_eq!("BitvSet {1u, 2u, 10u, 50u}", format!("{:?}", s)); + assert_eq!("BitvSet {1, 2, 10, 50}", format!("{:?}", s)); } #[test] diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index c56592177b4..8c2f00a5695 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -22,7 +22,7 @@ use core::borrow::BorrowFrom; use core::cmp::Ordering; use core::default::Default; -use core::fmt::Show; +use core::fmt::Debug; use core::hash::{Hash, Hasher}; use core::iter::{Map, FromIterator}; use core::ops::{Index, IndexMut}; @@ -871,7 +871,7 @@ fn cmp(&self, other: &BTreeMap) -> Ordering { } #[stable] -impl Show for BTreeMap { +impl Debug for BTreeMap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "BTreeMap {{")); diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index fa890643089..50857c78469 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -21,7 +21,7 @@ use core::borrow::BorrowFrom; use core::cmp::Ordering::{Greater, Less, Equal}; use core::iter::Zip; -use core::ops::{Deref, DerefMut}; +use core::ops::{Deref, DerefMut, Index, IndexMut}; use core::ptr::Unique; use core::{slice, mem, ptr, cmp, num, raw}; use alloc::heap; @@ -1487,7 +1487,7 @@ pub fn next_kv_item_back(&mut self) -> Option<(K, V)> { macro_rules! node_slice_impl { ($NodeSlice:ident, $Traversal:ident, - $as_slices_internal:ident, $slice_from:ident, $slice_to:ident, $iter:ident) => { + $as_slices_internal:ident, $index:ident, $iter:ident) => { impl<'a, K: Ord + 'a, V: 'a> $NodeSlice<'a, K, V> { /// Performs linear search in a slice. Returns a tuple of (index, is_exact_match). fn search_linear(&self, key: &Q) -> (uint, bool) @@ -1521,10 +1521,10 @@ pub fn slice_from(self, min_key: &K) -> $NodeSlice<'a, K, V> { edges: if !self.has_edges { self.edges } else { - self.edges.$slice_from(pos) + self.edges.$index(&(pos ..)) }, - keys: self.keys.slice_from(pos), - vals: self.vals.$slice_from(pos), + keys: &self.keys[pos ..], + vals: self.vals.$index(&(pos ..)), head_is_edge: !pos_is_kv, tail_is_edge: self.tail_is_edge, } @@ -1550,10 +1550,10 @@ pub fn slice_to(self, max_key: &K) -> $NodeSlice<'a, K, V> { edges: if !self.has_edges { self.edges } else { - self.edges.$slice_to(pos + 1) + self.edges.$index(&(.. (pos + 1))) }, - keys: self.keys.slice_to(pos), - vals: self.vals.$slice_to(pos), + keys: &self.keys[..pos], + vals: self.vals.$index(&(.. pos)), head_is_edge: self.head_is_edge, tail_is_edge: !pos_is_kv, } @@ -1583,6 +1583,5 @@ pub fn $iter(self) -> $Traversal<'a, K, V> { } } -node_slice_impl!(NodeSlice, Traversal, as_slices_internal, slice_from, slice_to, iter); -node_slice_impl!(MutNodeSlice, MutTraversal, as_slices_internal_mut, slice_from_mut, - slice_to_mut, iter_mut); +node_slice_impl!(NodeSlice, Traversal, as_slices_internal, index, iter); +node_slice_impl!(MutNodeSlice, MutTraversal, as_slices_internal_mut, index_mut, iter_mut); diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 4d71f9dbea8..d307b7dbde7 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -16,11 +16,8 @@ use core::borrow::BorrowFrom; use core::cmp::Ordering::{self, Less, Greater, Equal}; use core::default::Default; -use core::fmt::Show; +use core::fmt::Debug; use core::fmt; -// NOTE(stage0) remove import after a snapshot -#[cfg(stage0)] -use core::hash::Hash; use core::iter::{Peekable, Map, FromIterator}; use core::ops::{BitOr, BitAnd, BitXor, Sub}; @@ -592,7 +589,7 @@ fn bitor(self, rhs: &BTreeSet) -> BTreeSet { } #[stable] -impl Show for BTreeSet { +impl Debug for BTreeSet { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "BTreeSet {{")); @@ -892,7 +889,7 @@ fn test_show() { let set_str = format!("{:?}", set); - assert_eq!(set_str, "BTreeSet {1i, 2i}"); + assert_eq!(set_str, "BTreeSet {1, 2}"); assert_eq!(format!("{:?}", empty), "BTreeSet {}"); } } diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index cce8cf398e1..73fd806c907 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -874,7 +874,7 @@ fn clone(&self) -> DList { } #[stable] -impl fmt::Show for DList { +impl fmt::Debug for DList { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "DList [")); @@ -1333,7 +1333,7 @@ fn test_fuzz() { #[test] fn test_show() { let list: DList = range(0i, 10).collect(); - assert_eq!(format!("{:?}", list), "DList [0i, 1i, 2i, 3i, 4i, 5i, 6i, 7i, 8i, 9i]"); + assert_eq!(format!("{:?}", list), "DList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); let list: DList<&str> = vec!["just", "one", "test", "more"].iter() .map(|&s| s) diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 1b852d0ba68..a40a590c51a 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -31,7 +31,7 @@ pub struct EnumSet { impl Copy for EnumSet {} -impl fmt::Show for EnumSet { +impl fmt::Debug for EnumSet { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { try!(write!(fmt, "EnumSet {{")); let mut first = true; diff --git a/src/libcollections/macros.rs b/src/libcollections/macros.rs index c078db7d46f..85aedaeb010 100644 --- a/src/libcollections/macros.rs +++ b/src/libcollections/macros.rs @@ -12,13 +12,13 @@ #[macro_export] #[stable] macro_rules! vec { - ($x:expr; $y:expr) => ({ - let xs: $crate::boxed::Box<[_]> = $crate::boxed::Box::new([$x; $y]); - $crate::slice::SliceExt::into_vec(xs) - }); - ($($x:expr),*) => ({ - let xs: $crate::boxed::Box<[_]> = $crate::boxed::Box::new([$($x),*]); - $crate::slice::SliceExt::into_vec(xs) - }); + ($x:expr; $y:expr) => ( + <[_] as $crate::slice::SliceExt>::into_vec( + $crate::boxed::Box::new([$x; $y])) + ); + ($($x:expr),*) => ( + <[_] as $crate::slice::SliceExt>::into_vec( + $crate::boxed::Box::new([$($x),*])) + ); ($($x:expr,)*) => (vec![$($x),*]) } diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs index b9cb4be7c18..338166c2f0b 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/ring_buf.rs @@ -578,7 +578,7 @@ pub fn as_mut_slices<'a>(&'a mut self) -> (&'a mut [T], &'a mut [T]) { if contiguous { let (empty, buf) = buf.split_at_mut(0); - (buf.slice_mut(tail, head), empty) + (&mut buf[tail .. head], empty) } else { let (mid, right) = buf.split_at_mut(tail); let (left, _) = mid.split_at_mut(head); @@ -1611,7 +1611,7 @@ fn extend>(&mut self, mut iterator: T) { } #[stable] -impl fmt::Show for RingBuf { +impl fmt::Debug for RingBuf { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "RingBuf [")); @@ -1630,7 +1630,7 @@ mod tests { use self::Taggypar::*; use prelude::*; use core::iter; - use std::fmt::Show; + use std::fmt::Debug; use std::hash::{self, SipHasher}; use test::Bencher; use test; @@ -1678,7 +1678,7 @@ fn test_simple() { } #[cfg(test)] - fn test_parameterized(a: T, b: T, c: T, d: T) { + fn test_parameterized(a: T, b: T, c: T, d: T) { let mut deq = RingBuf::new(); assert_eq!(deq.len(), 0); deq.push_front(a.clone()); @@ -2302,7 +2302,7 @@ fn test_ord() { #[test] fn test_show() { let ringbuf: RingBuf = range(0i, 10).collect(); - assert_eq!(format!("{:?}", ringbuf), "RingBuf [0i, 1i, 2i, 3i, 4i, 5i, 6i, 7i, 8i, 9i]"); + assert_eq!(format!("{:?}", ringbuf), "RingBuf [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); let ringbuf: RingBuf<&str> = vec!["just", "one", "test", "more"].iter() .map(|&s| s) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 988ec4c661f..8c7f79d4d78 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -169,29 +169,16 @@ pub trait SliceExt { #[unstable = "uncertain about this API approach"] fn move_from(&mut self, src: Vec, start: uint, end: uint) -> uint; - /// Returns a subslice spanning the interval [`start`, `end`). - /// - /// Panics when the end of the new slice lies beyond the end of the - /// original slice (i.e. when `end > self.len()`) or when `start > end`. - /// - /// Slicing with `start` equal to `end` yields an empty slice. - #[unstable = "will be replaced by slice syntax"] + /// Deprecated: use `&s[start .. end]` notation instead. + #[deprecated = "use &s[start .. end] instead"] fn slice(&self, start: uint, end: uint) -> &[Self::Item]; - /// Returns a subslice from `start` to the end of the slice. - /// - /// Panics when `start` is strictly greater than the length of the original slice. - /// - /// Slicing from `self.len()` yields an empty slice. - #[unstable = "will be replaced by slice syntax"] + /// Deprecated: use `&s[start..]` notation instead. + #[deprecated = "use &s[start..] isntead"] fn slice_from(&self, start: uint) -> &[Self::Item]; - /// Returns a subslice from the start of the slice to `end`. - /// - /// Panics when `end` is strictly greater than the length of the original slice. - /// - /// Slicing to `0` yields an empty slice. - #[unstable = "will be replaced by slice syntax"] + /// Deprecated: use `&s[..end]` notation instead. + #[deprecated = "use &s[..end] instead"] fn slice_to(&self, end: uint) -> &[Self::Item]; /// Divides one slice into two at an index. @@ -378,29 +365,16 @@ fn is_empty(&self) -> bool { self.len() == 0 } #[stable] fn as_mut_slice(&mut self) -> &mut [Self::Item]; - /// Returns a mutable subslice spanning the interval [`start`, `end`). - /// - /// Panics when the end of the new slice lies beyond the end of the - /// original slice (i.e. when `end > self.len()`) or when `start > end`. - /// - /// Slicing with `start` equal to `end` yields an empty slice. - #[unstable = "will be replaced by slice syntax"] + /// Deprecated: use `&mut s[start .. end]` instead. + #[deprecated = "use &mut s[start .. end] instead"] fn slice_mut(&mut self, start: uint, end: uint) -> &mut [Self::Item]; - /// Returns a mutable subslice from `start` to the end of the slice. - /// - /// Panics when `start` is strictly greater than the length of the original slice. - /// - /// Slicing from `self.len()` yields an empty slice. - #[unstable = "will be replaced by slice syntax"] + /// Deprecated: use `&mut s[start ..]` instead. + #[deprecated = "use &mut s[start ..] instead"] fn slice_from_mut(&mut self, start: uint) -> &mut [Self::Item]; - /// Returns a mutable subslice from the start of the slice to `end`. - /// - /// Panics when `end` is strictly greater than the length of the original slice. - /// - /// Slicing to `0` yields an empty slice. - #[unstable = "will be replaced by slice syntax"] + /// Deprecated: use `&mut s[.. end]` instead. + #[deprecated = "use &mut s[.. end] instead"] fn slice_to_mut(&mut self, end: uint) -> &mut [Self::Item]; /// Returns an iterator that allows modifying each value @@ -712,7 +686,7 @@ fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering { #[inline] fn move_from(&mut self, mut src: Vec, start: uint, end: uint) -> uint { - for (a, b) in self.iter_mut().zip(src.slice_mut(start, end).iter_mut()) { + for (a, b) in self.iter_mut().zip(src[start .. end].iter_mut()) { mem::swap(a, b); } cmp::min(self.len(), end-start) @@ -720,17 +694,17 @@ fn move_from(&mut self, mut src: Vec, start: uint, end: uint) -> uint { #[inline] fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T] { - core_slice::SliceExt::slice(self, start, end) + &self[start .. end] } #[inline] fn slice_from<'a>(&'a self, start: uint) -> &'a [T] { - core_slice::SliceExt::slice_from(self, start) + &self[start ..] } #[inline] fn slice_to<'a>(&'a self, end: uint) -> &'a [T] { - core_slice::SliceExt::slice_to(self, end) + &self[.. end] } #[inline] @@ -834,17 +808,17 @@ fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] { #[inline] fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [T] { - core_slice::SliceExt::slice_mut(self, start, end) + &mut self[start .. end] } #[inline] fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T] { - core_slice::SliceExt::slice_from_mut(self, start) + &mut self[start ..] } #[inline] fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T] { - core_slice::SliceExt::slice_to_mut(self, end) + &mut self[.. end] } #[inline] @@ -2409,8 +2383,12 @@ fn test_windowsator_0() { #[test] fn test_chunksator() { + use core::iter::ExactSizeIterator; + let v = &[1i,2,3,4,5]; + assert_eq!(v.chunks(2).len(), 3); + let chunks: &[&[int]] = &[&[1i,2], &[3,4], &[5]]; assert_eq!(v.chunks(2).collect::>(), chunks); let chunks: &[&[int]] = &[&[1i,2,3], &[4,5]]; @@ -2476,19 +2454,19 @@ macro_rules! test_show_vec { } let empty: Vec = vec![]; test_show_vec!(empty, "[]"); - test_show_vec!(vec![1i], "[1i]"); - test_show_vec!(vec![1i, 2, 3], "[1i, 2i, 3i]"); + test_show_vec!(vec![1i], "[1]"); + test_show_vec!(vec![1i, 2, 3], "[1, 2, 3]"); test_show_vec!(vec![vec![], vec![1u], vec![1u, 1u]], - "[[], [1u], [1u, 1u]]"); + "[[], [1], [1, 1]]"); let empty_mut: &mut [int] = &mut[]; test_show_vec!(empty_mut, "[]"); let v: &mut[int] = &mut[1]; - test_show_vec!(v, "[1i]"); + test_show_vec!(v, "[1]"); let v: &mut[int] = &mut[1, 2, 3]; - test_show_vec!(v, "[1i, 2i, 3i]"); + test_show_vec!(v, "[1, 2, 3]"); let v: &mut [&mut[uint]] = &mut[&mut[], &mut[1u], &mut[1u, 1u]]; - test_show_vec!(v, "[[], [1u], [1u, 1u]]"); + test_show_vec!(v, "[[], [1], [1, 1]]"); } #[test] @@ -2675,7 +2653,10 @@ fn test_get_mut() { #[test] fn test_mut_chunks() { + use core::iter::ExactSizeIterator; + let mut v = [0u8, 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.iter_mut() { *x = i as u8; diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index f7668930660..6608d0ee9a7 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -750,67 +750,17 @@ fn lines_any(&self) -> LinesAny { core_str::StrExt::lines_any(&self[]) } - /// Returns a slice of the given string from the byte range - /// [`begin`..`end`). - /// - /// This operation is `O(1)`. - /// - /// Panics when `begin` and `end` do not point to valid characters - /// or point beyond the last character of the string. - /// - /// See also `slice_to` and `slice_from` for slicing prefixes and - /// suffixes of strings, and `slice_chars` for slicing based on - /// code point counts. - /// - /// # Example - /// - /// ```rust - /// let s = "Löwe 老虎 Léopard"; - /// assert_eq!(s.slice(0, 1), "L"); - /// - /// assert_eq!(s.slice(1, 9), "öwe 老"); - /// - /// // these will panic: - /// // byte 2 lies within `ö`: - /// // s.slice(2, 3); - /// - /// // byte 8 lies within `老` - /// // s.slice(1, 8); - /// - /// // byte 100 is outside the string - /// // s.slice(3, 100); - /// ``` - #[unstable = "use slice notation [a..b] instead"] - fn slice(&self, begin: uint, end: uint) -> &str { - core_str::StrExt::slice(&self[], begin, end) - } + /// Deprecated: use `s[a .. b]` instead. + #[deprecated = "use slice notation [a..b] instead"] + fn slice(&self, begin: uint, end: uint) -> &str; - /// Returns a slice of the string from `begin` to its end. - /// - /// Equivalent to `self.slice(begin, self.len())`. - /// - /// Panics when `begin` does not point to a valid character, or is - /// out of bounds. - /// - /// See also `slice`, `slice_to` and `slice_chars`. - #[unstable = "use slice notation [a..] instead"] - fn slice_from(&self, begin: uint) -> &str { - core_str::StrExt::slice_from(&self[], begin) - } + /// Deprecated: use `s[a..]` instead. + #[deprecated = "use slice notation [a..] instead"] + fn slice_from(&self, begin: uint) -> &str; - /// Returns a slice of the string from the beginning to byte - /// `end`. - /// - /// Equivalent to `self.slice(0, end)`. - /// - /// Panics when `end` does not point to a valid character, or is - /// out of bounds. - /// - /// See also `slice`, `slice_from` and `slice_chars`. - #[unstable = "use slice notation [..a] instead"] - fn slice_to(&self, end: uint) -> &str { - core_str::StrExt::slice_to(&self[], end) - } + /// Deprecated: use `s[..a]` instead. + #[deprecated = "use slice notation [..a] instead"] + fn slice_to(&self, end: uint) -> &str; /// Returns a slice of the string from the character range /// [`begin`..`end`). @@ -1348,7 +1298,19 @@ fn trim_right(&self) -> &str { } #[stable] -impl StrExt for str {} +impl StrExt for str { + fn slice(&self, begin: uint, end: uint) -> &str { + &self[begin..end] + } + + fn slice_from(&self, begin: uint) -> &str { + &self[begin..] + } + + fn slice_to(&self, end: uint) -> &str { + &self[..end] + } +} #[cfg(test)] mod tests { diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 5d35d8a8679..c965aedbc5d 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -18,6 +18,7 @@ use core::borrow::{Cow, IntoCow}; use core::default::Default; +use core::error::Error; use core::fmt; use core::hash; use core::iter::FromIterator; @@ -40,6 +41,7 @@ pub struct String { /// A possible error value from the `String::from_utf8` function. #[stable] +#[derive(Show)] pub struct FromUtf8Error { bytes: Vec, error: Utf8Error, @@ -48,6 +50,7 @@ pub struct FromUtf8Error { /// A possible error value from the `String::from_utf16` function. #[stable] #[allow(missing_copy_implementations)] +#[derive(Show)] pub struct FromUtf16Error(()); impl String { @@ -680,30 +683,28 @@ pub fn into_bytes(self) -> Vec { self.bytes } pub fn utf8_error(&self) -> Utf8Error { self.error } } -impl fmt::Show for FromUtf8Error { +#[stable] +impl fmt::Display for FromUtf8Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::String::fmt(self, f) + fmt::Display::fmt(&self.error, f) } } #[stable] -impl fmt::String for FromUtf8Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::String::fmt(&self.error, f) - } +impl Error for FromUtf8Error { + fn description(&self) -> &str { "invalid utf-8" } } -impl fmt::Show for FromUtf16Error { +#[stable] +impl fmt::Display for FromUtf16Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::String::fmt(self, f) + fmt::Display::fmt("invalid utf-16: lone surrogate found", f) } } #[stable] -impl fmt::String for FromUtf16Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::String::fmt("invalid utf-16: lone surrogate found", f) - } +impl Error for FromUtf16Error { + fn description(&self) -> &str { "invalid utf-16" } } #[stable] @@ -814,18 +815,18 @@ fn default() -> String { } #[stable] -impl fmt::String for String { +impl fmt::Display for String { #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::String::fmt(&**self, f) + fmt::Display::fmt(&**self, f) } } -#[unstable = "waiting on fmt stabilization"] -impl fmt::Show for String { +#[stable] +impl fmt::Debug for String { #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Show::fmt(&**self, f) + fmt::Debug::fmt(&**self, f) } } @@ -848,6 +849,7 @@ fn add(mut self, other: &str) -> String { } } +#[stable] impl ops::Index> for String { type Output = str; #[inline] @@ -855,6 +857,7 @@ fn index(&self, index: &ops::Range) -> &str { &self[][*index] } } +#[stable] impl ops::Index> for String { type Output = str; #[inline] @@ -862,6 +865,7 @@ fn index(&self, index: &ops::RangeTo) -> &str { &self[][*index] } } +#[stable] impl ops::Index> for String { type Output = str; #[inline] @@ -869,6 +873,7 @@ fn index(&self, index: &ops::RangeFrom) -> &str { &self[][*index] } } +#[stable] impl ops::Index for String { type Output = str; #[inline] @@ -934,7 +939,7 @@ pub trait ToString { fn to_string(&self) -> String; } -impl ToString for T { +impl ToString for T { #[inline] fn to_string(&self) -> String { use core::fmt::Writer; @@ -1295,10 +1300,10 @@ fn test_simple_types() { fn test_vectors() { let x: Vec = vec![]; assert_eq!(format!("{:?}", x), "[]"); - assert_eq!(format!("{:?}", vec![1i]), "[1i]"); - assert_eq!(format!("{:?}", vec![1i, 2, 3]), "[1i, 2i, 3i]"); + assert_eq!(format!("{:?}", vec![1i]), "[1]"); + assert_eq!(format!("{:?}", vec![1i, 2, 3]), "[1, 2, 3]"); assert!(format!("{:?}", vec![vec![], vec![1i], vec![1i, 1]]) == - "[[], [1i], [1i, 1i]]"); + "[[], [1], [1, 1]]"); } #[test] diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 4ddab8c533a..52590297a6a 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1229,7 +1229,7 @@ fn hash(&self, state: &mut S) { } } -#[unstable = "waiting on Index stability"] +#[stable] impl Index for Vec { type Output = T; @@ -1239,6 +1239,7 @@ fn index<'a>(&'a self, index: &uint) -> &'a T { } } +#[stable] impl IndexMut for Vec { type Output = T; @@ -1249,6 +1250,7 @@ fn index_mut<'a>(&'a mut self, index: &uint) -> &'a mut T { } +#[stable] impl ops::Index> for Vec { type Output = [T]; #[inline] @@ -1256,6 +1258,7 @@ fn index(&self, index: &ops::Range) -> &[T] { self.as_slice().index(index) } } +#[stable] impl ops::Index> for Vec { type Output = [T]; #[inline] @@ -1263,6 +1266,7 @@ fn index(&self, index: &ops::RangeTo) -> &[T] { self.as_slice().index(index) } } +#[stable] impl ops::Index> for Vec { type Output = [T]; #[inline] @@ -1270,6 +1274,7 @@ fn index(&self, index: &ops::RangeFrom) -> &[T] { self.as_slice().index(index) } } +#[stable] impl ops::Index for Vec { type Output = [T]; #[inline] @@ -1278,6 +1283,7 @@ fn index(&self, _index: &ops::FullRange) -> &[T] { } } +#[stable] impl ops::IndexMut> for Vec { type Output = [T]; #[inline] @@ -1285,6 +1291,7 @@ fn index_mut(&mut self, index: &ops::Range) -> &mut [T] { self.as_mut_slice().index_mut(index) } } +#[stable] impl ops::IndexMut> for Vec { type Output = [T]; #[inline] @@ -1292,6 +1299,7 @@ fn index_mut(&mut self, index: &ops::RangeTo) -> &mut [T] { self.as_mut_slice().index_mut(index) } } +#[stable] impl ops::IndexMut> for Vec { type Output = [T]; #[inline] @@ -1299,6 +1307,7 @@ fn index_mut(&mut self, index: &ops::RangeFrom) -> &mut [T] { self.as_mut_slice().index_mut(index) } } +#[stable] impl ops::IndexMut for Vec { type Output = [T]; #[inline] @@ -1307,7 +1316,6 @@ fn index_mut(&mut self, _index: &ops::FullRange) -> &mut [T] { } } - #[stable] impl ops::Deref for Vec { type Target = [T]; @@ -1486,10 +1494,10 @@ fn default() -> Vec { } } -#[unstable = "waiting on Show stability"] -impl fmt::Show for Vec { +#[stable] +impl fmt::Debug for Vec { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Show::fmt(self.as_slice(), f) + fmt::Debug::fmt(self.as_slice(), f) } } @@ -2158,7 +2166,7 @@ fn test_index_out_of_bounds() { #[should_fail] fn test_slice_out_of_bounds_1() { let x: Vec = vec![1, 2, 3, 4, 5]; - &x[(-1)..]; + &x[-1..]; } #[test] @@ -2172,7 +2180,7 @@ fn test_slice_out_of_bounds_2() { #[should_fail] fn test_slice_out_of_bounds_3() { let x: Vec = vec![1, 2, 3, 4, 5]; - &x[(-1)..4]; + &x[-1..4]; } #[test] diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 7ff2e953588..f178d5bc7e9 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -513,7 +513,7 @@ fn cmp(&self, other: &VecMap) -> Ordering { } #[stable] -impl fmt::Show for VecMap { +impl fmt::Debug for VecMap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "VecMap {{")); @@ -990,7 +990,7 @@ fn test_show() { map.insert(3, 4i); let map_str = format!("{:?}", map); - assert!(map_str == "VecMap {1: 2i, 3: 4i}" || map_str == "{3: 4i, 1: 2i}"); + assert!(map_str == "VecMap {1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}"); assert_eq!(format!("{:?}", empty), "VecMap {}"); } diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 20ed2253861..9966f0d4bf7 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -34,11 +34,11 @@ //! use runtime reflection instead. //! //! ```rust -//! use std::fmt::Show; +//! use std::fmt::Debug; //! use std::any::Any; //! -//! // Logger function for any type that implements Show. -//! fn log(value: &T) { +//! // Logger function for any type that implements Debug. +//! fn log(value: &T) { //! let value_any = value as &Any; //! //! // try to convert our value to a String. If successful, we want to @@ -55,7 +55,7 @@ //! } //! //! // This function wants to log its parameter out prior to doing work with it. -//! fn do_work(value: &T) { +//! fn do_work(value: &T) { //! log(value); //! // ...do some other work //! } @@ -75,7 +75,7 @@ use option::Option::{self, Some, None}; use raw::TraitObject; use intrinsics; -#[cfg(not(stage0))] use marker::Sized; +use marker::Sized; /////////////////////////////////////////////////////////////////////////////// // Any trait @@ -175,17 +175,10 @@ pub struct TypeId { impl TypeId { /// Returns the `TypeId` of the type this generic function has been /// instantiated with - #[cfg(not(stage0))] #[unstable = "may grow a `Reflect` bound soon via marker traits"] pub fn of() -> TypeId { TypeId { t: unsafe { intrinsics::type_id::() }, } } - - /// dox - #[cfg(stage0)] - pub fn of() -> TypeId { - unsafe { intrinsics::type_id::() } - } } diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 0cc31bf70de..a83537e12f7 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -39,10 +39,10 @@ fn hash(&self, state: &mut S) { } } - #[unstable = "waiting for Show to stabilize"] - impl fmt::Show for [T; $N] { + #[stable] + impl fmt::Debug for [T; $N] { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Show::fmt(&&self[], f) + fmt::Debug::fmt(&&self[], f) } } diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 4363a0a4441..63614aaa463 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -133,7 +133,6 @@ fn to_owned(&self) -> T { self.clone() } /// } /// } /// ``` -#[derive(Show)] pub enum Cow<'a, T, B: ?Sized + 'a> where B: ToOwned { /// Borrowed data. Borrowed(&'a B), @@ -239,14 +238,27 @@ fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option { } #[stable] -impl<'a, T, B: ?Sized> fmt::String for Cow<'a, T, B> where - B: fmt::String + ToOwned, - T: fmt::String, +impl<'a, T, B: ?Sized> fmt::Debug for Cow<'a, T, B> where + B: fmt::Debug + ToOwned, + T: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Borrowed(ref b) => fmt::String::fmt(b, f), - Owned(ref o) => fmt::String::fmt(o, f), + Borrowed(ref b) => fmt::Debug::fmt(b, f), + Owned(ref o) => fmt::Debug::fmt(o, f), + } + } +} + +#[stable] +impl<'a, T, B: ?Sized> fmt::Display for Cow<'a, T, B> where + B: fmt::Display + ToOwned, + T: fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Borrowed(ref b) => fmt::Display::fmt(b, f), + Owned(ref o) => fmt::Display::fmt(o, f), } } } diff --git a/src/libstd/error.rs b/src/libcore/error.rs similarity index 77% rename from src/libstd/error.rs rename to src/libcore/error.rs index ff128461978..9ff38028df9 100644 --- a/src/libstd/error.rs +++ b/src/libcore/error.rs @@ -14,14 +14,15 @@ //! //! `Error` is a trait representing the basic expectations for error values, //! i.e. values of type `E` in `Result`. At a minimum, errors must provide -//! a description, but they may optionally provide additional detail and cause -//! chain information: +//! a description, but they may optionally provide additional detail (via +//! `Display`) and cause chain information: //! //! ``` -//! trait Error { +//! use std::fmt::Display; +//! +//! trait Error: Display { //! fn description(&self) -> &str; //! -//! fn detail(&self) -> Option { None } //! fn cause(&self) -> Option<&Error> { None } //! } //! ``` @@ -80,20 +81,15 @@ #![stable] -use prelude::v1::*; - -use str::Utf8Error; -use string::{FromUtf8Error, FromUtf16Error}; +use prelude::*; +use fmt::Display; /// Base functionality for all errors in Rust. #[unstable = "the exact API of this trait may change"] -pub trait Error { +pub trait Error: Display { /// A short description of the error; usually a static string. fn description(&self) -> &str; - /// A detailed description of the error, usually including dynamic information. - fn detail(&self) -> Option { None } - /// The lower-level cause of this error, if any. fn cause(&self) -> Option<&Error> { None } } @@ -112,26 +108,3 @@ fn from_error(err: E) -> E { err } } - -#[stable] -impl Error for Utf8Error { - fn description(&self) -> &str { - match *self { - Utf8Error::TooShort => "invalid utf-8: not enough bytes", - Utf8Error::InvalidByte(..) => "invalid utf-8: corrupt contents", - } - } - - fn detail(&self) -> Option { Some(self.to_string()) } -} - -#[stable] -impl Error for FromUtf8Error { - fn description(&self) -> &str { "invalid utf-8" } - fn detail(&self) -> Option { Some(self.to_string()) } -} - -#[stable] -impl Error for FromUtf16Error { - fn description(&self) -> &str { "invalid utf-16" } -} diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index f1b9ebe6d90..245dc00d838 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -179,7 +179,7 @@ pub fn float_to_str_bytes_common( _ => () } - buf.slice_to_mut(end).reverse(); + buf[..end].reverse(); // Remember start of the fractional digits. // Points one beyond end of buf if none get generated, @@ -316,7 +316,7 @@ struct Filler<'a> { impl<'a> fmt::Writer for Filler<'a> { fn write_str(&mut self, s: &str) -> fmt::Result { - slice::bytes::copy_memory(self.buf.slice_from_mut(*self.end), + slice::bytes::copy_memory(&mut self.buf[(*self.end)..], s.as_bytes()); *self.end += s.len(); Ok(()) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 535722f93bf..0e8d31a62ee 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -26,12 +26,15 @@ use result; use slice::SliceExt; use slice; -use str::{self, StrExt, Utf8Error}; +use str::{self, StrExt}; pub use self::num::radix; pub use self::num::Radix; pub use self::num::RadixFmt; +#[cfg(stage0)] pub use self::Debug as Show; +#[cfg(stage0)] pub use self::Display as String; + mod num; mod float; pub mod rt; @@ -46,7 +49,7 @@ /// occurred. Any extra information must be arranged to be transmitted through /// some other means. #[unstable = "core and I/O reconciliation may alter this definition"] -#[derive(Copy)] +#[derive(Copy, Show)] pub struct Error; /// A collection of methods that are required to format a message into a stream. @@ -133,7 +136,7 @@ pub struct Argument<'a> { impl<'a> Argument<'a> { #[inline(never)] fn show_uint(x: &uint, f: &mut Formatter) -> Result { - Show::fmt(x, f) + Display::fmt(x, f) } fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter) -> Result) -> Argument<'b> { @@ -214,14 +217,15 @@ pub struct Arguments<'a> { args: &'a [Argument<'a>], } -impl<'a> Show for Arguments<'a> { +#[stable] +impl<'a> Debug for Arguments<'a> { fn fmt(&self, fmt: &mut Formatter) -> Result { - String::fmt(self, fmt) + Display::fmt(self, fmt) } } #[stable] -impl<'a> String for Arguments<'a> { +impl<'a> Display for Arguments<'a> { fn fmt(&self, fmt: &mut Formatter) -> Result { write(fmt.buf, *self) } @@ -229,20 +233,49 @@ fn fmt(&self, fmt: &mut Formatter) -> Result { /// Format trait for the `:?` format. Useful for debugging, most all types /// should implement this. -#[unstable = "I/O and core have yet to be reconciled"] +#[deprecated = "renamed to Debug"] +#[cfg(not(stage0))] pub trait Show { /// Formats the value using the given formatter. fn fmt(&self, &mut Formatter) -> Result; } +/// Format trait for the `:?` format. Useful for debugging, most all types +/// should implement this. +#[unstable = "I/O and core have yet to be reconciled"] +pub trait Debug { + /// Formats the value using the given formatter. + fn fmt(&self, &mut Formatter) -> Result; +} + +#[cfg(not(stage0))] +impl Debug for T { + #[allow(deprecated)] + fn fmt(&self, f: &mut Formatter) -> Result { Show::fmt(self, f) } +} + +/// When a value can be semantically expressed as a String, this trait may be +/// used. It corresponds to the default format, `{}`. +#[deprecated = "renamed to Display"] +#[cfg(not(stage0))] +pub trait String { + /// Formats the value using the given formatter. + fn fmt(&self, &mut Formatter) -> Result; +} + /// When a value can be semantically expressed as a String, this trait may be /// used. It corresponds to the default format, `{}`. #[unstable = "I/O and core have yet to be reconciled"] -pub trait String { +pub trait Display { /// Formats the value using the given formatter. fn fmt(&self, &mut Formatter) -> Result; } +#[cfg(not(stage0))] +impl Display for T { + #[allow(deprecated)] + fn fmt(&self, f: &mut Formatter) -> Result { String::fmt(self, f) } +} /// Format trait for the `o` character #[unstable = "I/O and core have yet to be reconciled"] @@ -583,9 +616,10 @@ pub fn width(&self) -> Option { self.width } pub fn precision(&self) -> Option { self.precision } } -impl Show for Error { +#[stable] +impl Display for Error { fn fmt(&self, f: &mut Formatter) -> Result { - String::fmt("an error occurred when formatting an argument", f) + Display::fmt("an error occurred when formatting an argument", f) } } @@ -611,9 +645,11 @@ pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> { macro_rules! fmt_refs { ($($tr:ident),*) => { $( + #[stable] impl<'a, T: ?Sized + $tr> $tr for &'a T { fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) } } + #[stable] impl<'a, T: ?Sized + $tr> $tr for &'a mut T { fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) } } @@ -621,22 +657,24 @@ fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) } } } -fmt_refs! { Show, String, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } +fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } -impl Show for bool { +#[stable] +impl Debug for bool { fn fmt(&self, f: &mut Formatter) -> Result { - String::fmt(self, f) + Display::fmt(self, f) } } #[stable] -impl String for bool { +impl Display for bool { fn fmt(&self, f: &mut Formatter) -> Result { - String::fmt(if *self { "true" } else { "false" }, f) + Display::fmt(if *self { "true" } else { "false" }, f) } } -impl Show for str { +#[stable] +impl Debug for str { fn fmt(&self, f: &mut Formatter) -> Result { try!(write!(f, "\"")); for c in self.chars().flat_map(|c| c.escape_default()) { @@ -647,13 +685,14 @@ fn fmt(&self, f: &mut Formatter) -> Result { } #[stable] -impl String for str { +impl Display for str { fn fmt(&self, f: &mut Formatter) -> Result { f.pad(self) } } -impl Show for char { +#[stable] +impl Debug for char { fn fmt(&self, f: &mut Formatter) -> Result { use char::CharExt; try!(write!(f, "'")); @@ -665,15 +704,16 @@ fn fmt(&self, f: &mut Formatter) -> Result { } #[stable] -impl String for char { +impl Display for char { fn fmt(&self, f: &mut Formatter) -> Result { let mut utf8 = [0u8; 4]; let amt = self.encode_utf8(&mut utf8).unwrap_or(0); let s: &str = unsafe { mem::transmute(&utf8[..amt]) }; - String::fmt(s, f) + Display::fmt(s, f) } } +#[stable] impl Pointer for *const T { fn fmt(&self, f: &mut Formatter) -> Result { f.flags |= 1 << (rt::FlagAlternate as uint); @@ -683,18 +723,21 @@ fn fmt(&self, f: &mut Formatter) -> Result { } } +#[stable] impl Pointer for *mut T { fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(&(*self as *const T), f) } } +#[stable] impl<'a, T> Pointer for &'a T { fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(&(*self as *const T), f) } } +#[stable] impl<'a, T> Pointer for &'a mut T { fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(&(&**self as *const T), f) @@ -703,15 +746,15 @@ fn fmt(&self, f: &mut Formatter) -> Result { macro_rules! floating { ($ty:ident) => { - impl Show for $ty { + #[stable] + impl Debug for $ty { fn fmt(&self, fmt: &mut Formatter) -> Result { - try!(String::fmt(self, fmt)); - fmt.write_str(stringify!($ty)) + Display::fmt(self, fmt) } } #[stable] - impl String for $ty { + impl Display for $ty { fn fmt(&self, fmt: &mut Formatter) -> Result { use num::Float; @@ -732,6 +775,7 @@ fn fmt(&self, fmt: &mut Formatter) -> Result { } } + #[stable] impl LowerExp for $ty { fn fmt(&self, fmt: &mut Formatter) -> Result { use num::Float; @@ -753,6 +797,7 @@ fn fmt(&self, fmt: &mut Formatter) -> Result { } } + #[stable] impl UpperExp for $ty { fn fmt(&self, fmt: &mut Formatter) -> Result { use num::Float; @@ -777,12 +822,14 @@ fn fmt(&self, fmt: &mut Formatter) -> Result { floating! { f32 } floating! { f64 } -// Implementation of Show for various core types +// Implementation of Display/Debug for various core types -impl Show for *const T { +#[stable] +impl Debug for *const T { fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } } -impl Show for *mut T { +#[stable] +impl Debug for *mut T { fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } } @@ -793,7 +840,8 @@ macro_rules! peel { macro_rules! tuple { () => (); ( $($name:ident,)+ ) => ( - impl<$($name:Show),*> Show for ($($name,)*) { + #[stable] + impl<$($name:Debug),*> Debug for ($($name,)*) { #[allow(non_snake_case, unused_assignments)] fn fmt(&self, f: &mut Formatter) -> Result { try!(write!(f, "(")); @@ -818,11 +866,13 @@ fn fmt(&self, f: &mut Formatter) -> Result { tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } -impl<'a> Show for &'a (any::Any+'a) { +#[stable] +impl<'a> Debug for &'a (any::Any+'a) { fn fmt(&self, f: &mut Formatter) -> Result { f.pad("&Any") } } -impl Show for [T] { +#[stable] +impl Debug for [T] { fn fmt(&self, f: &mut Formatter) -> Result { if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 { try!(write!(f, "[")); @@ -843,20 +893,22 @@ fn fmt(&self, f: &mut Formatter) -> Result { } } -impl Show for () { +#[stable] +impl Debug for () { fn fmt(&self, f: &mut Formatter) -> Result { f.pad("()") } } -impl Show for Cell { +#[stable] +impl Debug for Cell { fn fmt(&self, f: &mut Formatter) -> Result { write!(f, "Cell {{ value: {:?} }}", self.get()) } } -#[unstable] -impl Show for RefCell { +#[stable] +impl Debug for RefCell { fn fmt(&self, f: &mut Formatter) -> Result { match self.try_borrow() { Some(val) => write!(f, "RefCell {{ value: {:?} }}", val), @@ -865,29 +917,17 @@ fn fmt(&self, f: &mut Formatter) -> Result { } } -impl<'b, T: Show> Show for Ref<'b, T> { +#[stable] +impl<'b, T: Debug> Debug for Ref<'b, T> { fn fmt(&self, f: &mut Formatter) -> Result { - Show::fmt(&**self, f) - } -} - -impl<'b, T: Show> Show for RefMut<'b, T> { - fn fmt(&self, f: &mut Formatter) -> Result { - Show::fmt(&*(self.deref()), f) + Debug::fmt(&**self, f) } } #[stable] -impl String for Utf8Error { +impl<'b, T: Debug> Debug for RefMut<'b, T> { fn fmt(&self, f: &mut Formatter) -> Result { - match *self { - Utf8Error::InvalidByte(n) => { - write!(f, "invalid utf-8: invalid byte at index {}", n) - } - Utf8Error::TooShort => { - write!(f, "invalid utf-8: byte slice too short") - } - } + Debug::fmt(&*(self.deref()), f) } } diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 1df6f845225..c456b3379e8 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -154,13 +154,14 @@ pub fn radix(x: T, base: u8) -> RadixFmt { macro_rules! radix_fmt { ($T:ty as $U:ty, $fmt:ident, $S:expr) => { - impl fmt::Show for RadixFmt<$T, Radix> { + #[stable] + impl fmt::Debug for RadixFmt<$T, Radix> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(fmt::String::fmt(self, f)); - f.write_str($S) + fmt::Display::fmt(self, f) } } - impl fmt::String for RadixFmt<$T, Radix> { + #[stable] + impl fmt::Display for RadixFmt<$T, Radix> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { RadixFmt(ref x, radix) => radix.$fmt(*x as $U, f) } } @@ -169,6 +170,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } macro_rules! int_base { ($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => { + #[stable] impl fmt::$Trait for $T { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { $Radix.fmt_int(*self as $U, f) @@ -179,10 +181,10 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { macro_rules! show { ($T:ident with $S:expr) => { - impl fmt::Show for $T { + #[stable] + impl fmt::Debug for $T { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(fmt::String::fmt(self, f)); - f.write_str($S) + fmt::Display::fmt(self, f) } } } @@ -192,7 +194,7 @@ macro_rules! integer { integer! { $Int, $Uint, stringify!($Int), stringify!($Uint) } }; ($Int:ident, $Uint:ident, $SI:expr, $SU:expr) => { - int_base! { String for $Int as $Int -> Decimal } + 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 } @@ -200,7 +202,7 @@ macro_rules! integer { radix_fmt! { $Int as $Int, fmt_int, $SI } show! { $Int with $SI } - int_base! { String for $Uint as $Uint -> Decimal } + 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 } diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 73be68289c9..dd488a74216 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -44,8 +44,6 @@ use marker::Sized; -#[cfg(stage0)] use any::TypeId; - pub type GlueFn = extern "Rust" fn(*const i8); #[lang="ty_desc"] @@ -208,12 +206,8 @@ pub struct TyDesc { /// Gets an identifier which is globally unique to the specified type. This /// function will return the same value for a type regardless of whichever /// crate it is invoked in. - #[cfg(not(stage0))] pub fn type_id() -> u64; - #[cfg(stage0)] - pub fn type_id() -> TypeId; - /// Create a value initialized to zero. /// /// `init` is unsafe because it returns a zeroed-out datum, diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 0005db36c27..773ac99b0de 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -99,6 +99,20 @@ pub trait Iterator { fn size_hint(&self) -> (uint, Option) { (0, None) } } +// FIXME(#21363) remove `old_impl_check` when bug is fixed +#[old_impl_check] +impl<'a, T> Iterator for &'a mut (Iterator + 'a) { + type Item = T; + + fn next(&mut self) -> Option { + (**self).next() + } + + fn size_hint(&self) -> (usize, Option) { + (**self).size_hint() + } +} + /// Conversion from an `Iterator` #[stable] #[rustc_on_unimplemented="a collection of type `{Self}` cannot be \ @@ -2701,63 +2715,93 @@ fn next(&mut self) -> Option { } } +macro_rules! range_impl { + ($($t:ty)*) => ($( + #[stable] + impl Iterator for ::ops::Range<$t> { + type Item = $t; -/// The `Step` trait identifies objects which can be stepped over in both -/// directions. The `steps_between` function provides a way to -/// compare two Step objects (it could be provided using `step()` and `Ord`, -/// but the implementation would be so inefficient as to be useless). -#[unstable = "design of range notation/iteration is in flux"] -pub trait Step: Ord { - /// Change self to the next object. - fn step(&mut self); - /// Change self to the previous object. - fn step_back(&mut self); - /// The steps_between two step objects. - /// start should always be less than end, so the result should never be negative. - /// Return None if it is not possible to calculate steps_between without - /// overflow. - fn steps_between(start: &Self, end: &Self) -> Option; + #[inline] + fn next(&mut self) -> Option<$t> { + if self.start < self.end { + let result = self.start; + self.start += 1; + return Some(result); + } + + return None; + } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + debug_assert!(self.end >= self.start); + let hint = (self.end - self.start) as uint; + (hint, Some(hint)) + } + } + + #[stable] + impl ExactSizeIterator for ::ops::Range<$t> {} + )*) } -macro_rules! step_impl { +macro_rules! range_impl_no_hint { ($($t:ty)*) => ($( - #[unstable = "Trait is unstable."] - impl Step for $t { + #[stable] + impl Iterator for ::ops::Range<$t> { + type Item = $t; + #[inline] - fn step(&mut self) { *self += 1; } - #[inline] - fn step_back(&mut self) { *self -= 1; } - #[inline] - fn steps_between(start: &$t, end: &$t) -> Option { - debug_assert!(end >= start); - Some((*end - *start) as uint) + fn next(&mut self) -> Option<$t> { + if self.start < self.end { + let result = self.start; + self.start += 1; + return Some(result); + } + + return None; } } )*) } -macro_rules! step_impl_no_between { +macro_rules! range_other_impls { ($($t:ty)*) => ($( - #[unstable = "Trait is unstable."] - impl Step for $t { + #[stable] + impl DoubleEndedIterator for ::ops::Range<$t> { #[inline] - fn step(&mut self) { *self += 1; } + fn next_back(&mut self) -> Option<$t> { + if self.start < self.end { + self.end -= 1; + return Some(self.end); + } + + return None; + } + } + + #[stable] + impl Iterator for ::ops::RangeFrom<$t> { + type Item = $t; + #[inline] - fn step_back(&mut self) { *self -= 1; } - #[inline] - fn steps_between(_start: &$t, _end: &$t) -> Option { - None + fn next(&mut self) -> Option<$t> { + let result = self.start; + self.start += 1; + debug_assert!(result < self.start); + return Some(result); } } )*) } -step_impl!(uint u8 u16 u32 int i8 i16 i32); +range_impl!(uint u8 u16 u32 int i8 i16 i32); #[cfg(target_pointer_width = "64")] -step_impl!(u64 i64); +range_impl!(u64 i64); #[cfg(target_pointer_width = "32")] -step_impl_no_between!(u64 i64); +range_impl_no_hint!(u64 i64); +range_other_impls!(uint u8 u16 u32 u64 int i8 i16 i32 i64); /// An iterator that repeats an element endlessly #[derive(Clone)] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 0b150d1ecf9..1e271f972b1 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -63,6 +63,8 @@ #![feature(unboxed_closures)] #![allow(unknown_features)] #![feature(int_uint)] #![feature(on_unimplemented)] +// FIXME(#21363) remove `old_impl_check` when bug is fixed +#![feature(old_impl_check)] #![deny(missing_docs)] #[macro_use] @@ -136,6 +138,7 @@ pub mod str; pub mod hash; pub mod fmt; +pub mod error; // note: does not need to be public mod tuple; diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 99ba9666cd2..a987a0a5068 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -376,16 +376,6 @@ fn clone(&self) -> InvariantType { *self } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct InvariantLifetime<'a>; -/// A type which is considered "not sendable", meaning that it cannot -/// be safely sent between tasks, even if it is owned. This is -/// typically embedded in other types, such as `Gc`, to ensure that -/// their instances remain thread-local. -#[unstable = "likely to change with new variance strategy"] -#[lang="no_send_bound"] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -#[cfg(stage0)] // NOTE remove impl after next snapshot -pub struct NoSend; - /// A type which is considered "not POD", meaning that it is not /// implicitly copyable. This is typically embedded in other types to /// ensure that they are never copied, even if they lack a destructor. @@ -395,15 +385,6 @@ fn clone(&self) -> InvariantType { *self } #[allow(missing_copy_implementations)] pub struct NoCopy; -/// A type which is considered "not sync", meaning that -/// its contents are not threadsafe, hence they cannot be -/// shared between tasks. -#[unstable = "likely to change with new variance strategy"] -#[lang="no_sync_bound"] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -#[cfg(stage0)] // NOTE remove impl after next snapshot -pub struct NoSync; - /// A type which is considered managed by the GC. This is typically /// embedded in other types. #[unstable = "likely to change with new variance strategy"] diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 905de9ef615..372596cdd44 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -33,8 +33,6 @@ //! demonstrates adding and subtracting two `Point`s. //! //! ```rust -//! #![feature(associated_types)] -//! //! use std::ops::{Add, Sub}; //! //! #[derive(Show)] @@ -69,10 +67,7 @@ #![stable] -use clone::Clone; -use iter::{Step, Iterator,DoubleEndedIterator,ExactSizeIterator}; use marker::Sized; -use option::Option::{self, Some, None}; use fmt; /// The `Drop` trait is used to run some code when a value goes out of scope. This @@ -164,8 +159,6 @@ fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output { /// calling `add`, and therefore, `main` prints `Adding!`. /// /// ```rust -/// #![feature(associated_types)] -/// /// use std::ops::Add; /// /// #[derive(Copy)] @@ -219,8 +212,6 @@ fn add(self, other: $t) -> $t { self + other } /// calling `sub`, and therefore, `main` prints `Subtracting!`. /// /// ```rust -/// #![feature(associated_types)] -/// /// use std::ops::Sub; /// /// #[derive(Copy)] @@ -274,8 +265,6 @@ fn sub(self, other: $t) -> $t { self - other } /// calling `mul`, and therefore, `main` prints `Multiplying!`. /// /// ```rust -/// #![feature(associated_types)] -/// /// use std::ops::Mul; /// /// #[derive(Copy)] @@ -329,8 +318,6 @@ fn mul(self, other: $t) -> $t { self * other } /// calling `div`, and therefore, `main` prints `Dividing!`. /// /// ``` -/// #![feature(associated_types)] -/// /// use std::ops::Div; /// /// #[derive(Copy)] @@ -384,8 +371,6 @@ fn div(self, other: $t) -> $t { self / other } /// calling `rem`, and therefore, `main` prints `Remainder-ing!`. /// /// ``` -/// #![feature(associated_types)] -/// /// use std::ops::Rem; /// /// #[derive(Copy)] @@ -458,8 +443,6 @@ fn rem(self, other: $t) -> $t { /// `neg`, and therefore, `main` prints `Negating!`. /// /// ``` -/// #![feature(associated_types)] -/// /// use std::ops::Neg; /// /// struct Foo; @@ -537,8 +520,6 @@ fn neg(self) -> $t { -(self as $t_signed) as $t } /// `not`, and therefore, `main` prints `Not-ing!`. /// /// ``` -/// #![feature(associated_types)] -/// /// use std::ops::Not; /// /// struct Foo; @@ -593,8 +574,6 @@ fn not(self) -> $t { !self } /// calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`. /// /// ``` -/// #![feature(associated_types)] -/// /// use std::ops::BitAnd; /// /// #[derive(Copy)] @@ -648,8 +627,6 @@ fn bitand(self, rhs: $t) -> $t { self & rhs } /// calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`. /// /// ``` -/// #![feature(associated_types)] -/// /// use std::ops::BitOr; /// /// #[derive(Copy)] @@ -703,8 +680,6 @@ fn bitor(self, rhs: $t) -> $t { self | rhs } /// calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`. /// /// ``` -/// #![feature(associated_types)] -/// /// use std::ops::BitXor; /// /// #[derive(Copy)] @@ -758,8 +733,6 @@ fn bitxor(self, other: $t) -> $t { self ^ other } /// calling `shl`, and therefore, `main` prints `Shifting left!`. /// /// ``` -/// #![feature(associated_types)] -/// /// use std::ops::Shl; /// /// #[derive(Copy)] @@ -831,8 +804,6 @@ macro_rules! shl_impl_all { /// calling `shr`, and therefore, `main` prints `Shifting right!`. /// /// ``` -/// #![feature(associated_types)] -/// /// use std::ops::Shr; /// /// #[derive(Copy)] @@ -924,10 +895,12 @@ macro_rules! shr_impl_all { /// } /// ``` #[lang="index"] +#[stable] pub trait Index { type Output: ?Sized; /// The method for the indexing (`Foo[Bar]`) operation + #[stable] fn index<'a>(&'a self, index: &Index) -> &'a Self::Output; } @@ -960,30 +933,32 @@ pub trait Index { /// } /// ``` #[lang="index_mut"] +#[stable] pub trait IndexMut { type Output: ?Sized; /// The method for the indexing (`Foo[Bar]`) operation + #[stable] fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Self::Output; } /// An unbounded range. #[derive(Copy, Clone, PartialEq, Eq)] #[lang="full_range"] -#[unstable = "API still in development"] +#[unstable = "may be renamed to RangeFull"] pub struct FullRange; -#[unstable = "API still in development"] -impl fmt::Show for FullRange { +#[stable] +impl fmt::Debug for FullRange { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt::Show::fmt("..", fmt) + fmt::Debug::fmt("..", fmt) } } /// A (half-open) range which is bounded at both ends. #[derive(Copy, Clone, PartialEq, Eq)] #[lang="range"] -#[unstable = "API still in development"] +#[stable] pub struct Range { /// The lower bound of the range (inclusive). pub start: Idx, @@ -991,49 +966,8 @@ pub struct Range { pub end: Idx, } -#[unstable = "API still in development"] -impl Iterator for Range { - type Item = Idx; - - #[inline] - fn next(&mut self) -> Option { - if self.start < self.end { - let result = self.start.clone(); - self.start.step(); - return Some(result); - } - - return None; - } - - #[inline] - fn size_hint(&self) -> (uint, Option) { - if let Some(hint) = Step::steps_between(&self.start, &self.end) { - (hint, Some(hint)) - } else { - (0, None) - } - } -} - -#[unstable = "API still in development"] -impl DoubleEndedIterator for Range { - #[inline] - fn next_back(&mut self) -> Option { - if self.start < self.end { - self.end.step_back(); - return Some(self.end.clone()); - } - - return None; - } -} - -#[unstable = "API still in development"] -impl ExactSizeIterator for Range {} - -#[unstable = "API still in development"] -impl fmt::Show for Range { +#[stable] +impl fmt::Debug for Range { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{:?}..{:?}", self.start, self.end) } @@ -1042,27 +976,16 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { /// A range which is only bounded below. #[derive(Copy, Clone, PartialEq, Eq)] #[lang="range_from"] -#[unstable = "API still in development"] +#[stable] pub struct RangeFrom { /// The lower bound of the range (inclusive). pub start: Idx, } -#[unstable = "API still in development"] -impl Iterator for RangeFrom { - type Item = Idx; - #[inline] - fn next(&mut self) -> Option { - // Deliberately overflow so we loop forever. - let result = self.start.clone(); - self.start.step(); - return Some(result); - } -} -#[unstable = "API still in development"] -impl fmt::Show for RangeFrom { +#[stable] +impl fmt::Debug for RangeFrom { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{:?}..", self.start) } @@ -1071,14 +994,14 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { /// A range which is only bounded above. #[derive(Copy, Clone, PartialEq, Eq)] #[lang="range_to"] -#[unstable = "API still in development"] +#[stable] pub struct RangeTo { /// The upper bound of the range (exclusive). pub end: Idx, } -#[unstable = "API still in development"] -impl fmt::Show for RangeTo { +#[stable] +impl fmt::Debug for RangeTo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "..{:?}", self.end) } @@ -1094,8 +1017,6 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { /// struct. /// /// ``` -/// #![feature(associated_types)] -/// /// use std::ops::Deref; /// /// struct DerefExample { @@ -1149,8 +1070,6 @@ fn deref(&self) -> &T { *self } /// struct. /// /// ``` -/// #![feature(associated_types)] -/// /// use std::ops::{Deref, DerefMut}; /// /// struct DerefMutExample { diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 1ab810f937d..c3d49e24978 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -229,7 +229,7 @@ use self::Result::{Ok, Err}; use clone::Clone; -use fmt::Show; +use fmt::Display; use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator}; use ops::{FnMut, FnOnce}; use option::Option::{self, None, Some}; @@ -714,7 +714,7 @@ pub fn unwrap_or_else T>(self, op: F) -> T { } #[stable] -impl Result { +impl Result { /// Unwraps a result, yielding the content of an `Ok`. /// /// # Panics @@ -739,13 +739,13 @@ pub fn unwrap(self) -> T { match self { Ok(t) => t, Err(e) => - panic!("called `Result::unwrap()` on an `Err` value: {:?}", e) + panic!("called `Result::unwrap()` on an `Err` value: {}", e) } } } #[stable] -impl Result { +impl Result { /// Unwraps a result, yielding the content of an `Err`. /// /// # Panics @@ -769,7 +769,7 @@ impl Result { pub fn unwrap_err(self) -> E { match self { Ok(t) => - panic!("called `Result::unwrap_err()` on an `Ok` value: {:?}", t), + panic!("called `Result::unwrap_err()` on an `Ok` value: {}", t), Err(e) => e } } diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 50cbb7a61dc..ec43a35248e 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -67,9 +67,6 @@ pub trait SliceExt { type Item; - fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [Self::Item]; - fn slice_from<'a>(&'a self, start: uint) -> &'a [Self::Item]; - fn slice_to<'a>(&'a self, end: uint) -> &'a [Self::Item]; fn split_at<'a>(&'a self, mid: uint) -> (&'a [Self::Item], &'a [Self::Item]); fn iter<'a>(&'a self) -> Iter<'a, Self::Item>; fn split<'a, P>(&'a self, pred: P) -> Split<'a, Self::Item, P> @@ -93,9 +90,6 @@ fn binary_search_by(&self, f: F) -> Result where fn is_empty(&self) -> bool { self.len() == 0 } fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut Self::Item>; fn as_mut_slice<'a>(&'a mut self) -> &'a mut [Self::Item]; - fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [Self::Item]; - fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [Self::Item]; - fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [Self::Item]; fn iter_mut<'a>(&'a mut self) -> IterMut<'a, Self::Item>; fn first_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>; fn tail_mut<'a>(&'a mut self) -> &'a mut [Self::Item]; @@ -135,28 +129,6 @@ fn rsplitn_mut

(&mut self, n: uint, pred: P) -> RSplitNMut impl SliceExt for [T] { type Item = T; - #[inline] - fn slice(&self, start: uint, end: uint) -> &[T] { - assert!(start <= end); - assert!(end <= self.len()); - unsafe { - transmute(RawSlice { - data: self.as_ptr().offset(start as int), - len: (end - start) - }) - } - } - - #[inline] - fn slice_from(&self, start: uint) -> &[T] { - self.slice(start, self.len()) - } - - #[inline] - fn slice_to(&self, end: uint) -> &[T] { - self.slice(0, end) - } - #[inline] fn split_at(&self, mid: uint) -> (&[T], &[T]) { (&self[..mid], &self[mid..]) @@ -240,7 +212,7 @@ fn tail(&self) -> &[T] { &self[1..] } #[inline] fn init(&self) -> &[T] { - &self[..(self.len() - 1)] + &self[..self.len() - 1] } #[inline] @@ -291,20 +263,6 @@ fn get_mut(&mut self, index: uint) -> Option<&mut T> { #[inline] fn as_mut_slice(&mut self) -> &mut [T] { self } - fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T] { - ops::IndexMut::index_mut(self, &ops::Range { start: start, end: end } ) - } - - #[inline] - fn slice_from_mut(&mut self, start: uint) -> &mut [T] { - ops::IndexMut::index_mut(self, &ops::RangeFrom { start: start } ) - } - - #[inline] - fn slice_to_mut(&mut self, end: uint) -> &mut [T] { - ops::IndexMut::index_mut(self, &ops::RangeTo { end: end } ) - } - #[inline] fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]) { unsafe { @@ -345,13 +303,13 @@ fn first_mut(&mut self) -> Option<&mut T> { #[inline] fn tail_mut(&mut self) -> &mut [T] { - self.slice_from_mut(1) + &mut self[1 ..] } #[inline] fn init_mut(&mut self) -> &mut [T] { let len = self.len(); - self.slice_to_mut(len-1) + &mut self[.. (len - 1)] } #[inline] @@ -449,7 +407,7 @@ fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq { #[inline] fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq { let (m, n) = (self.len(), needle.len()); - m >= n && needle == &self[(m-n)..] + m >= n && needle == &self[m-n..] } #[unstable] @@ -483,7 +441,7 @@ fn next_permutation(&mut self) -> bool where T: Ord { self.swap(j, i-1); // Step 4: Reverse the (previously) weakly decreasing part - self.slice_from_mut(i).reverse(); + self[i..].reverse(); true } @@ -505,7 +463,7 @@ fn prev_permutation(&mut self) -> bool where T: Ord { } // Step 2: Reverse the weakly increasing part - self.slice_from_mut(i).reverse(); + self[i..].reverse(); // Step 3: Find the rightmost element equal to or bigger than the pivot (i-1) let mut j = self.len() - 1; @@ -522,8 +480,8 @@ fn prev_permutation(&mut self) -> bool where T: Ord { #[inline] fn clone_from_slice(&mut self, src: &[T]) -> uint where T: Clone { let min = cmp::min(self.len(), src.len()); - let dst = self.slice_to_mut(min); - let src = src.slice_to(min); + let dst = &mut self[.. min]; + let src = &src[.. min]; for i in range(0, min) { dst[i].clone_from(&src[i]); } @@ -531,6 +489,7 @@ fn clone_from_slice(&mut self, src: &[T]) -> uint where T: Clone { } } +#[stable] impl ops::Index for [T] { type Output = T; @@ -541,6 +500,7 @@ fn index(&self, &index: &uint) -> &T { } } +#[stable] impl ops::IndexMut for [T] { type Output = T; @@ -551,6 +511,7 @@ fn index_mut(&mut self, &index: &uint) -> &mut T { } } +#[stable] impl ops::Index> for [T] { type Output = [T]; #[inline] @@ -565,6 +526,7 @@ fn index(&self, index: &ops::Range) -> &[T] { } } } +#[stable] impl ops::Index> for [T] { type Output = [T]; #[inline] @@ -572,6 +534,7 @@ fn index(&self, index: &ops::RangeTo) -> &[T] { self.index(&ops::Range{ start: 0, end: index.end }) } } +#[stable] impl ops::Index> for [T] { type Output = [T]; #[inline] @@ -579,6 +542,7 @@ fn index(&self, index: &ops::RangeFrom) -> &[T] { self.index(&ops::Range{ start: index.start, end: self.len() }) } } +#[stable] impl ops::Index for [T] { type Output = [T]; #[inline] @@ -587,6 +551,7 @@ fn index(&self, _index: &ops::FullRange) -> &[T] { } } +#[stable] impl ops::IndexMut> for [T] { type Output = [T]; #[inline] @@ -601,6 +566,7 @@ fn index_mut(&mut self, index: &ops::Range) -> &mut [T] { } } } +#[stable] impl ops::IndexMut> for [T] { type Output = [T]; #[inline] @@ -608,6 +574,7 @@ fn index_mut(&mut self, index: &ops::RangeTo) -> &mut [T] { self.index_mut(&ops::Range{ start: 0, end: index.end }) } } +#[stable] impl ops::IndexMut> for [T] { type Output = [T]; #[inline] @@ -616,6 +583,7 @@ fn index_mut(&mut self, index: &ops::RangeFrom) -> &mut [T] { self.index_mut(&ops::Range{ start: index.start, end: len }) } } +#[stable] impl ops::IndexMut for [T] { type Output = [T]; #[inline] @@ -973,7 +941,7 @@ fn next(&mut self) -> Option<&'a [T]> { None => self.finish(), Some(idx) => { let ret = Some(&self.v[..idx]); - self.v = &self.v[(idx + 1)..]; + self.v = &self.v[idx + 1..]; ret } } @@ -998,7 +966,7 @@ fn next_back(&mut self) -> Option<&'a [T]> { match self.v.iter().rposition(|x| (self.pred)(x)) { None => self.finish(), Some(idx) => { - let ret = Some(&self.v[(idx + 1)..]); + let ret = Some(&self.v[idx + 1..]); self.v = &self.v[..idx]; ret } @@ -1051,7 +1019,7 @@ fn next(&mut self) -> Option<&'a mut [T]> { Some(idx) => { let tmp = mem::replace(&mut self.v, &mut []); let (head, tail) = tmp.split_at_mut(idx); - self.v = tail.slice_from_mut(1); + self.v = &mut tail[1..]; Some(head) } } @@ -1087,7 +1055,7 @@ fn next_back(&mut self) -> Option<&'a mut [T]> { let tmp = mem::replace(&mut self.v, &mut []); let (head, tail) = tmp.split_at_mut(idx); self.v = head; - Some(tail.slice_from_mut(1)) + Some(&mut tail[1..]) } } } @@ -1269,6 +1237,9 @@ fn next_back(&mut self) -> Option<&'a [T]> { } } +#[stable] +impl<'a, T> ExactSizeIterator for Chunks<'a, T> {} + #[unstable = "trait is experimental"] impl<'a, T> RandomAccessIterator for Chunks<'a, T> { #[inline] @@ -1347,6 +1318,8 @@ fn next_back(&mut self) -> Option<&'a mut [T]> { } } +#[stable] +impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {} // // Free functions diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 6a542b2c458..bdac686cb66 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -20,8 +20,10 @@ use cmp::{self, Eq}; use default::Default; -use iter::range; +use error::Error; +use fmt; use iter::ExactSizeIterator; +use iter::range; use iter::{Map, Iterator, IteratorExt, DoubleEndedIterator}; use marker::Sized; use mem; @@ -242,6 +244,30 @@ fn only_ascii(&self) -> bool { } } +#[stable] +impl Error for Utf8Error { + fn description(&self) -> &str { + match *self { + Utf8Error::TooShort => "invalid utf-8: not enough bytes", + Utf8Error::InvalidByte(..) => "invalid utf-8: corrupt contents", + } + } +} + +#[stable] +impl fmt::Display for Utf8Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Utf8Error::InvalidByte(n) => { + write!(f, "invalid utf-8: invalid byte at index {}", n) + } + Utf8Error::TooShort => { + write!(f, "invalid utf-8: byte slice too short") + } + } + } +} + /* Section: Iterators */ @@ -902,13 +928,13 @@ fn next(&mut self) -> Option<&'a str> { match self.it.next() { Some((from, to)) => { - let ret = Some(self.it.haystack.slice(self.last_end, from)); + let ret = Some(&self.it.haystack[self.last_end .. from]); self.last_end = to; ret } None => { self.finished = true; - Some(self.it.haystack.slice(self.last_end, self.it.haystack.len())) + Some(&self.it.haystack[self.last_end .. self.it.haystack.len()]) } } } @@ -1115,27 +1141,90 @@ fn partial_cmp(&self, other: &str) -> Option { } } + /// Returns a slice of the given string from the byte range + /// [`begin`..`end`). + /// + /// This operation is `O(1)`. + /// + /// Panics when `begin` and `end` do not point to valid characters + /// or point beyond the last character of the string. + /// + /// # Example + /// + /// ```rust + /// let s = "Löwe 老虎 Léopard"; + /// assert_eq!(&s[0 .. 1], "L"); + /// + /// assert_eq!(&s[1 .. 9], "öwe 老"); + /// + /// // these will panic: + /// // byte 2 lies within `ö`: + /// // &s[2 ..3]; + /// + /// // byte 8 lies within `老` + /// // &s[1 .. 8]; + /// + /// // byte 100 is outside the string + /// // &s[3 .. 100]; + /// ``` + #[stable] impl ops::Index> for str { type Output = str; #[inline] fn index(&self, index: &ops::Range) -> &str { - self.slice(index.start, index.end) + // is_char_boundary checks that the index is in [0, .len()] + if index.start <= index.end && + self.is_char_boundary(index.start) && + self.is_char_boundary(index.end) { + unsafe { self.slice_unchecked(index.start, index.end) } + } else { + super::slice_error_fail(self, index.start, index.end) + } } } + + /// Returns a slice of the string from the beginning to byte + /// `end`. + /// + /// Equivalent to `self[0 .. end]`. + /// + /// Panics when `end` does not point to a valid character, or is + /// out of bounds. + #[stable] impl ops::Index> for str { type Output = str; #[inline] fn index(&self, index: &ops::RangeTo) -> &str { - self.slice_to(index.end) + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(index.end) { + unsafe { self.slice_unchecked(0, index.end) } + } else { + super::slice_error_fail(self, 0, index.end) + } } } + + /// Returns a slice of the string from `begin` to its end. + /// + /// Equivalent to `self[begin .. self.len()]`. + /// + /// Panics when `begin` does not point to a valid character, or is + /// out of bounds. + #[stable] impl ops::Index> for str { type Output = str; #[inline] fn index(&self, index: &ops::RangeFrom) -> &str { - self.slice_from(index.start) + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(index.start) { + unsafe { self.slice_unchecked(index.start, self.len()) } + } else { + super::slice_error_fail(self, index.start, self.len()) + } } } + + #[stable] impl ops::Index for str { type Output = str; #[inline] @@ -1147,7 +1236,7 @@ fn index(&self, _index: &ops::FullRange) -> &str { /// Any string that can be represented as a slice #[unstable = "Instead of taking this bound generically, this trait will be \ - replaced with one of slicing syntax, deref coercions, or \ + replaced with one of slicing syntax (&foo[]), deref coercions, or \ a more generic conversion trait"] pub trait Str { /// Work with `self` as a slice. @@ -1208,9 +1297,6 @@ pub trait StrExt { fn lines<'a>(&'a self) -> Lines<'a>; fn lines_any<'a>(&'a self) -> LinesAny<'a>; fn char_len(&self) -> uint; - fn slice<'a>(&'a self, begin: uint, end: uint) -> &'a str; - fn slice_from<'a>(&'a self, begin: uint) -> &'a str; - fn slice_to<'a>(&'a self, end: uint) -> &'a str; fn slice_chars<'a>(&'a self, begin: uint, end: uint) -> &'a str; unsafe fn slice_unchecked<'a>(&'a self, begin: uint, end: uint) -> &'a str; fn starts_with(&self, pat: &str) -> bool; @@ -1332,7 +1418,7 @@ fn lines(&self) -> Lines { fn lines_any(&self) -> LinesAny { fn f(line: &str) -> &str { let l = line.len(); - if l > 0 && line.as_bytes()[l - 1] == b'\r' { line.slice(0, l - 1) } + if l > 0 && line.as_bytes()[l - 1] == b'\r' { &line[0 .. l - 1] } else { line } } @@ -1343,38 +1429,6 @@ fn f(line: &str) -> &str { #[inline] fn char_len(&self) -> uint { self.chars().count() } - #[inline] - fn slice(&self, begin: uint, end: uint) -> &str { - // is_char_boundary checks that the index is in [0, .len()] - if begin <= end && - self.is_char_boundary(begin) && - self.is_char_boundary(end) { - unsafe { self.slice_unchecked(begin, end) } - } else { - slice_error_fail(self, begin, end) - } - } - - #[inline] - fn slice_from(&self, begin: uint) -> &str { - // is_char_boundary checks that the index is in [0, .len()] - if self.is_char_boundary(begin) { - unsafe { self.slice_unchecked(begin, self.len()) } - } else { - slice_error_fail(self, begin, self.len()) - } - } - - #[inline] - fn slice_to(&self, end: uint) -> &str { - // is_char_boundary checks that the index is in [0, .len()] - if self.is_char_boundary(end) { - unsafe { self.slice_unchecked(0, end) } - } else { - slice_error_fail(self, 0, end) - } - } - fn slice_chars(&self, begin: uint, end: uint) -> &str { assert!(begin <= end); let mut count = 0; @@ -1415,7 +1469,7 @@ fn starts_with(&self, needle: &str) -> bool { #[inline] fn ends_with(&self, needle: &str) -> bool { let (m, n) = (self.len(), needle.len()); - m >= n && needle.as_bytes() == &self.as_bytes()[(m-n)..] + m >= n && needle.as_bytes() == &self.as_bytes()[m-n..] } #[inline] diff --git a/src/libcoretest/finally.rs b/src/libcoretest/finally.rs index 979ddaecb4a..6ec87203e00 100644 --- a/src/libcoretest/finally.rs +++ b/src/libcoretest/finally.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use core::finally::{try_finally, Finally}; use std::thread::Thread; diff --git a/src/libcoretest/fmt/num.rs b/src/libcoretest/fmt/num.rs index c259e4cbb68..eb278d2cc90 100644 --- a/src/libcoretest/fmt/num.rs +++ b/src/libcoretest/fmt/num.rs @@ -26,11 +26,11 @@ fn test_format_int() { assert!(format!("{}", -1i16) == "-1"); assert!(format!("{}", -1i32) == "-1"); assert!(format!("{}", -1i64) == "-1"); - assert!(format!("{:?}", 1i) == "1i"); - assert!(format!("{:?}", 1i8) == "1i8"); - assert!(format!("{:?}", 1i16) == "1i16"); - assert!(format!("{:?}", 1i32) == "1i32"); - assert!(format!("{:?}", 1i64) == "1i64"); + assert!(format!("{:?}", 1i) == "1"); + assert!(format!("{:?}", 1i8) == "1"); + assert!(format!("{:?}", 1i16) == "1"); + assert!(format!("{:?}", 1i32) == "1"); + assert!(format!("{:?}", 1i64) == "1"); assert!(format!("{:b}", 1i) == "1"); assert!(format!("{:b}", 1i8) == "1"); assert!(format!("{:b}", 1i16) == "1"); @@ -57,11 +57,11 @@ fn test_format_int() { assert!(format!("{}", 1u16) == "1"); assert!(format!("{}", 1u32) == "1"); assert!(format!("{}", 1u64) == "1"); - assert!(format!("{:?}", 1u) == "1u"); - assert!(format!("{:?}", 1u8) == "1u8"); - assert!(format!("{:?}", 1u16) == "1u16"); - assert!(format!("{:?}", 1u32) == "1u32"); - assert!(format!("{:?}", 1u64) == "1u64"); + assert!(format!("{:?}", 1u) == "1"); + assert!(format!("{:?}", 1u8) == "1"); + assert!(format!("{:?}", 1u16) == "1"); + assert!(format!("{:?}", 1u32) == "1"); + assert!(format!("{:?}", 1u64) == "1"); assert!(format!("{:b}", 1u) == "1"); assert!(format!("{:b}", 1u8) == "1"); assert!(format!("{:b}", 1u16) == "1"); @@ -94,14 +94,14 @@ fn test_format_int() { #[test] fn test_format_int_zero() { assert!(format!("{}", 0i) == "0"); - assert!(format!("{:?}", 0i) == "0i"); + assert!(format!("{:?}", 0i) == "0"); assert!(format!("{:b}", 0i) == "0"); assert!(format!("{:o}", 0i) == "0"); assert!(format!("{:x}", 0i) == "0"); assert!(format!("{:X}", 0i) == "0"); assert!(format!("{}", 0u) == "0"); - assert!(format!("{:?}", 0u) == "0u"); + assert!(format!("{:?}", 0u) == "0"); assert!(format!("{:b}", 0u) == "0"); assert!(format!("{:o}", 0u) == "0"); assert!(format!("{:x}", 0u) == "0"); diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index 26819bf9209..4bbbde6b48c 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -585,7 +585,7 @@ fn check_randacc_iter(a: T, len: uint) where fn test_double_ended_flat_map() { let u = [0u,1]; let v = [5u,6,7,8]; - let mut it = u.iter().flat_map(|x| v[(*x)..v.len()].iter()); + let mut it = u.iter().flat_map(|x| v[*x..v.len()].iter()); assert_eq!(it.next_back().unwrap(), &8); assert_eq!(it.next().unwrap(), &5); assert_eq!(it.next_back().unwrap(), &7); diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs index 8186a4f0904..e0623bade5c 100644 --- a/src/libcoretest/num/mod.rs +++ b/src/libcoretest/num/mod.rs @@ -9,7 +9,7 @@ // except according to those terms. use core::cmp::PartialEq; -use core::fmt::Show; +use core::fmt::Debug; use core::num::{NumCast, cast}; use core::ops::{Add, Sub, Mul, Div, Rem}; use core::marker::Copy; @@ -37,7 +37,7 @@ pub fn test_num(ten: T, two: T) where T: PartialEq + NumCast + Add + Sub + Mul + Div - + Rem + Show + + Rem + Debug + Copy { assert_eq!(ten.add(two), cast(12i).unwrap()); diff --git a/src/libcoretest/result.rs b/src/libcoretest/result.rs index 485549cc552..daccb709890 100644 --- a/src/libcoretest/result.rs +++ b/src/libcoretest/result.rs @@ -14,11 +14,11 @@ pub fn op2() -> Result { Err("sadface") } #[test] pub fn test_and() { assert_eq!(op1().and(Ok(667i)).unwrap(), 667); - assert_eq!(op1().and(Err::<(), &'static str>("bad")).unwrap_err(), + assert_eq!(op1().and(Err::("bad")).unwrap_err(), "bad"); assert_eq!(op2().and(Ok(667i)).unwrap_err(), "sadface"); - assert_eq!(op2().and(Err::<(),&'static str>("bad")).unwrap_err(), + assert_eq!(op2().and(Err::("bad")).unwrap_err(), "sadface"); } @@ -94,7 +94,7 @@ pub fn test_fmt_default() { let err: Result = Err("Err"); let s = format!("{:?}", ok); - assert_eq!(s, "Ok(100i)"); + assert_eq!(s, "Ok(100)"); let s = format!("{:?}", err); assert_eq!(s, "Err(\"Err\")"); } diff --git a/src/libcoretest/tuple.rs b/src/libcoretest/tuple.rs index 62eb9f4ad34..e524d8de056 100644 --- a/src/libcoretest/tuple.rs +++ b/src/libcoretest/tuple.rs @@ -60,9 +60,9 @@ fn test_tuple_cmp() { #[test] fn test_show() { let s = format!("{:?}", (1i,)); - assert_eq!(s, "(1i,)"); + assert_eq!(s, "(1,)"); let s = format!("{:?}", (1i, true)); - assert_eq!(s, "(1i, true)"); + assert_eq!(s, "(1, true)"); let s = format!("{:?}", (1i, "hi", true)); - assert_eq!(s, "(1i, \"hi\", true)"); + assert_eq!(s, "(1, \"hi\", true)"); } diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index c2114d4c6df..70f2429282b 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -544,7 +544,7 @@ pub fn to_err_msg(self) -> String { } } -impl fmt::String for Fail { +impl fmt::Display for Fail { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { ArgumentMissing(ref nm) => { @@ -893,7 +893,7 @@ fn each_split_within(ss: &str, lim: uint, mut it: F) -> bool where (B, Cr, UnderLim) => { B } (B, Cr, OverLim) if (i - last_start + 1) > lim => panic!("word starting with {} longer than limit!", - &ss[last_start..(i + 1)]), + &ss[last_start..i + 1]), (B, Cr, OverLim) => { *cont = it(&ss[slice_start..last_end]); slice_start = last_start; diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 2d7d88f0f35..0ed32b7bf4f 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -358,19 +358,19 @@ impl<'a> Id<'a> { /// /// Passing an invalid string (containing spaces, brackets, /// quotes, ...) will return an empty `Err` value. - pub fn new>(name: Name) -> Result, ()> { + pub fn new>(name: Name) -> Option> { let name = name.into_cow(); { let mut chars = name.chars(); match chars.next() { Some(c) if is_letter_or_underscore(c) => { ; }, - _ => return Err(()) + _ => return None } if !chars.all(is_constituent) { - return Err(()); + return None } } - return Ok(Id{ name: name }); + return Some(Id{ name: name }); fn is_letter_or_underscore(c: char) -> bool { in_range('a', c, 'z') || in_range('A', c, 'Z') || c == '_' @@ -874,8 +874,8 @@ fn left_aligned_text() { fn simple_id_construction() { let id1 = Id::new("hello"); match id1 { - Ok(_) => {;}, - Err(_) => panic!("'hello' is not a valid value for id anymore") + Some(_) => {;}, + None => panic!("'hello' is not a valid value for id anymore") } } @@ -883,8 +883,8 @@ fn simple_id_construction() { fn badly_formatted_id() { let id2 = Id::new("Weird { struct : ure } !!!"); match id2 { - Ok(_) => panic!("graphviz id suddenly allows spaces, brackets and stuff"), - Err(_) => {;} + Some(_) => panic!("graphviz id suddenly allows spaces, brackets and stuff"), + None => {;} } } } diff --git a/src/libgraphviz/maybe_owned_vec.rs b/src/libgraphviz/maybe_owned_vec.rs index 567fe04c5af..4e6437a5e76 100644 --- a/src/libgraphviz/maybe_owned_vec.rs +++ b/src/libgraphviz/maybe_owned_vec.rs @@ -124,7 +124,7 @@ fn from_iter>(iterator: I) -> MaybeOwnedVector<'a,T> { } } -impl<'a,T:fmt::Show> fmt::Show for MaybeOwnedVector<'a,T> { +impl<'a,T:fmt::Debug> fmt::Debug for MaybeOwnedVector<'a,T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.as_slice().fmt(f) } diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index fa6468517e6..677a5f37a1b 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -4648,13 +4648,13 @@ pub mod signal { use types::os::arch::c95::c_int; use types::os::common::posix01::sighandler_t; - #[cfg(not(target_os = "android"))] + #[cfg(not(all(target_os = "android", target_arch = "arm")))] extern { pub fn signal(signum: c_int, handler: sighandler_t) -> sighandler_t; } - #[cfg(target_os = "android")] + #[cfg(all(target_os = "android", target_arch = "arm"))] extern { #[link_name = "bsd_signal"] pub fn signal(signum: c_int, diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index dbd88434127..4da07c50c59 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -180,6 +180,7 @@ use std::io; use std::mem; use std::os; +use std::ptr; use std::rt; use std::slice; use std::sync::{Once, ONCE_INIT}; @@ -239,21 +240,15 @@ struct DefaultLogger { } /// Wraps the log level with fmt implementations. -#[derive(Copy, PartialEq, PartialOrd)] +#[derive(Copy, PartialEq, PartialOrd, Show)] pub struct LogLevel(pub u32); -impl fmt::Show for LogLevel { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt::String::fmt(self, fmt) - } -} - -impl fmt::String for LogLevel { +impl fmt::Display for LogLevel { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let LogLevel(level) = *self; match LOG_LEVEL_NAMES.get(level as uint - 1) { - Some(ref name) => fmt::String::fmt(name, fmt), - None => fmt::String::fmt(&level, fmt) + Some(ref name) => fmt::Display::fmt(name, fmt), + None => fmt::Display::fmt(&level, fmt) } } } @@ -437,11 +432,11 @@ fn init() { assert!(!DIRECTIVES.is_null()); let _directives: Box> = mem::transmute(DIRECTIVES); - DIRECTIVES = 0 as *const Vec; + DIRECTIVES = ptr::null(); if !FILTER.is_null() { let _filter: Box = mem::transmute(FILTER); - FILTER = 0 as *const _; + FILTER = ptr::null(); } }); } diff --git a/src/librand/chacha.rs b/src/librand/chacha.rs index 815fc0e7ec7..3332e06e19e 100644 --- a/src/librand/chacha.rs +++ b/src/librand/chacha.rs @@ -174,7 +174,7 @@ fn reseed(&mut self, seed: &'a [u32]) { // reset state self.init(&[0u32; KEY_WORDS]); // set key in place - let key = self.state.slice_mut(4, 4+KEY_WORDS); + let key = &mut self.state[4 .. 4+KEY_WORDS]; for (k, s) in key.iter_mut().zip(seed.iter()) { *k = *s; } @@ -292,4 +292,3 @@ fn test_rng_clone() { } } } - diff --git a/src/librbml/io.rs b/src/librbml/io.rs index f39860c8695..9c746c69baa 100644 --- a/src/librbml/io.rs +++ b/src/librbml/io.rs @@ -103,7 +103,7 @@ fn write(&mut self, buf: &[u8]) -> IoResult<()> { // Do the necessary writes if left.len() > 0 { - slice::bytes::copy_memory(self.buf.slice_from_mut(self.pos), left); + slice::bytes::copy_memory(&mut self.buf[self.pos..], left); } if right.len() > 0 { self.buf.push_all(right); diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index 25279796c03..50fe56ff5c0 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -38,6 +38,7 @@ pub use self::Error::*; use std::str; +use std::fmt; pub mod io; @@ -113,6 +114,13 @@ pub enum Error { IoError(std::io::IoError), ApplicationError(String) } + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // FIXME: this should be a more useful display form + fmt::Debug::fmt(self, f) + } +} // -------------------------------------- pub mod reader { diff --git a/src/libregex/parse.rs b/src/libregex/parse.rs index 1cc2b271e9c..c2186a0ec24 100644 --- a/src/libregex/parse.rs +++ b/src/libregex/parse.rs @@ -30,6 +30,7 @@ /// /// (Once an expression is compiled, it is not possible to produce an error /// via searching, splitting or replacing.) +#[derive(Show)] pub struct Error { /// The *approximate* character index of where the error occurred. pub pos: uint, @@ -37,7 +38,7 @@ pub struct Error { pub msg: String, } -impl fmt::Show for Error { +impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Regex syntax error near position {}: {:?}", self.pos, self.msg) @@ -518,7 +519,7 @@ fn parse_counted(&mut self) -> Result<(), Error> { }; self.chari = closer; let greed = try!(self.get_next_greedy()); - let inner = self.chars[(start+1)..closer].iter().cloned() + let inner = self.chars[start+1..closer].iter().cloned() .collect::(); // Parse the min and max values from the regex. diff --git a/src/libregex/re.rs b/src/libregex/re.rs index abc51d62404..1b68ad500ca 100644 --- a/src/libregex/re.rs +++ b/src/libregex/re.rs @@ -90,10 +90,10 @@ fn clone(&self) -> ExNative { } } -impl fmt::String for Regex { +impl fmt::Display for Regex { /// Shows the original regular expression. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::String::fmt(self.as_str(), f) + fmt::Display::fmt(self.as_str(), f) } } @@ -459,7 +459,7 @@ pub fn pos(&self, i: uint) -> Option<(uint, uint)> { pub fn at(&self, i: uint) -> Option<&'t str> { match self.pos(i) { None => None, - Some((s, e)) => Some(self.text.slice(s, e)) + Some((s, e)) => Some(&self.text[s.. e]) } } diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 1ea79bdf606..b48df36a679 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -10,28 +10,55 @@ #![allow(non_snake_case)] -register_diagnostic! { E0001, r##" +register_long_diagnostics! { + E0001: r##" This error suggests that the expression arm corresponding to the noted pattern will never be reached as for all possible values of the expression being matched, one of the preceeding patterns will match. This means that perhaps some of the preceeding patterns are too general, this one is too specific or the ordering is incorrect. -"## } +"##, + + E0003: r##" + Not-a-Number (NaN) values can not be compared for equality and hence can never match + the input to a match expression. To match against NaN values, you should instead use + the `is_nan` method in a guard, as in: x if x.is_nan() => ... +"##, + + E0004: r##" + This error indicates that the compiler can not guarantee a matching pattern for one + or more possible inputs to a match expression. Guaranteed matches are required in order + to assign values to match expressions, or alternatively, determine the flow of execution. + + If you encounter this error you must alter your patterns so that every possible value of + the input type is matched. For types with a small number of variants (like enums) you + should probably cover all cases explicitly. Alternatively, the underscore `_` wildcard + pattern can be added after all other patterns to match "anything else". +"##, + + // FIXME: Remove duplication here? + E0005: r##" + Patterns used to bind names must be irrefutable, that is, they must guarantee that a + name will be extracted in all cases. If you encounter this error you probably need + to use a `match` or `if let` to deal with the possibility of failure. +"##, + + E0006: r##" + Patterns used to bind names must be irrefutable, that is, they must guarantee that a + name will be extracted in all cases. If you encounter this error you probably need + to use a `match` or `if let` to deal with the possibility of failure. +"## +} register_diagnostics! { E0002, - E0003, - E0004, - E0005, - E0006, E0007, E0008, E0009, E0010, E0011, E0012, - E0013, E0014, E0015, E0016, @@ -49,24 +76,58 @@ E0137, E0138, E0139, - E0140, E0152, - E0153, - E0157, E0158, E0161, E0162, E0165, - E0166, - E0167, - E0168, - E0169, E0170, - E0171, - E0172, - E0173, - E0174, - E0177, - E0178, - E0179 + E0261, // use of undeclared lifetime name + E0262, // illegal lifetime parameter name + E0263, // lifetime name declared twice in same scope + E0264, // unknown external lang item + E0265, // recursive constant + E0266, // expected item + E0267, // thing inside of a closure + E0268, // thing outside of a loop + E0269, // not all control paths return a value + E0270, // computation may converge in a function marked as diverging + E0271, // type mismatch resolving + E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter + E0273, // rustc_on_unimplemented must have named format arguments + E0274, // rustc_on_unimplemented must have a value + E0275, // overflow evaluating requirement + E0276, // requirement appears on impl method but not on corresponding trait method + E0277, // trait is not implemented for type + E0278, // requirement is not satisfied + E0279, // requirement is not satisfied + E0280, // requirement is not satisfied + E0281, // type implements trait but other trait is required + E0282, // unable to infer enough type information about + E0283, // cannot resolve type + E0284, // cannot resolve type + E0285, // overflow evaluation builtin bounds + E0296, // malformed recursion limit attribute + E0297, // refutable pattern in for loop binding + E0298, // mismatched types between arms + E0299, // mismatched types between arms + E0300, // unexpanded macro + E0301, // cannot mutable borrow in a pattern guard + E0302, // cannot assign in a pattern guard + E0303, // pattern bindings are not allowed after an `@` + E0304, // expected signed integer constant + E0305, // expected constant + E0306, // expected positive integer for repeat count + E0307, // expected constant integer for repeat count + E0308, + E0309, // thing may not live long enough + E0310, // thing may not live long enough + E0311, // thing may not live long enough + E0312, // lifetime of reference outlives lifetime of borrowed content + E0313, // lifetime of borrowed pointer outlives lifetime of captured variable + E0314, // closure outlives stack frame + E0315 // cannot invoke closure outside of its lifetime } + +__build_diagnostic_array! { DIAGNOSTICS } + diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 62869064551..377e5dd39ff 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -54,7 +54,9 @@ pub use rustc_llvm as llvm; -mod diagnostics; +// NB: This module needs to be declared first so diagnostics are +// registered before they are used. +pub mod diagnostics; pub mod back { pub use rustc_back::abi; @@ -132,8 +134,6 @@ pub mod lib { pub use llvm; } -__build_diagnostic_array! { DIAGNOSTICS } - // A private module so that macro-expanded idents like // `::rustc::lint::Lint` will also work in `rustc` itself. // diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 8a27cfc510f..fef1017b782 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -1202,17 +1202,17 @@ fn get_lints(&self) -> LintArray { lint_array!(UNUSED_IMPORT_BRACES) } - fn check_view_item(&mut self, cx: &Context, view_item: &ast::ViewItem) { - match view_item.node { - ast::ViewItemUse(ref view_path) => { + fn check_item(&mut self, cx: &Context, item: &ast::Item) { + match item.node { + ast::ItemUse(ref view_path) => { match view_path.node { - ast::ViewPathList(_, ref items, _) => { + ast::ViewPathList(_, ref items) => { if items.len() == 1 { match items[0].node { ast::PathListIdent {ref name, ..} => { let m = format!("braces around {} is unnecessary", token::get_ident(*name).get()); - cx.span_lint(UNUSED_IMPORT_BRACES, view_item.span, + cx.span_lint(UNUSED_IMPORT_BRACES, item.span, &m[]); }, _ => () @@ -1329,7 +1329,7 @@ fn check_unused_mut_pat(&self, cx: &Context, pats: &[P]) { let ident = path1.node; if let ast::BindByValue(ast::MutMutable) = mode { if !token::get_ident(ident).get().starts_with("_") { - match mutables.entry(ident.name.uint()) { + match mutables.entry(ident.name.usize()) { Vacant(entry) => { entry.insert(vec![id]); }, Occupied(mut entry) => { entry.get_mut().push(id); }, } @@ -1709,22 +1709,6 @@ fn check_crate(&mut self, _: &Context, c: &ast::Crate) { } } - fn check_view_item(&mut self, cx: &Context, item: &ast::ViewItem) { - // compiler-generated `extern crate` statements have a dummy span. - if item.span == DUMMY_SP { return } - - let id = match item.node { - ast::ViewItemExternCrate(_, _, id) => id, - ast::ViewItemUse(..) => return, - }; - let cnum = match cx.tcx.sess.cstore.find_extern_mod_stmt_cnum(id) { - Some(cnum) => cnum, - None => return, - }; - let id = ast::DefId { krate: cnum, node: ast::CRATE_NODE_ID }; - self.lint(cx, id, item.span); - } - fn check_expr(&mut self, cx: &Context, e: &ast::Expr) { if self.is_internal(cx, e.span) { return; } @@ -1776,6 +1760,17 @@ fn check_item(&mut self, cx: &Context, item: &ast::Item) { if self.is_internal(cx, item.span) { return } match item.node { + ast::ItemExternCrate(_) => { + // compiler-generated `extern crate` items have a dummy span. + if item.span == DUMMY_SP { return } + + let cnum = match cx.tcx.sess.cstore.find_extern_mod_stmt_cnum(item.id) { + Some(cnum) => cnum, + None => return, + }; + let id = ast::DefId { krate: cnum, node: ast::CRATE_NODE_ID }; + self.lint(cx, id, item.span); + } ast::ItemTrait(_, _, ref supertraits, _) => { for t in supertraits.iter() { if let ast::TraitTyParamBound(ref t, _) = *t { diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index de4efe09f27..4cbfcf7e91a 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -231,30 +231,7 @@ macro_rules! add_lint_group { // We have one lint pass defined in this module. self.register_pass(sess, false, box GatherNodeLevels as LintPassObject); - // Insert temporary renamings for a one-time deprecation (#16545) - self.register_renamed("unnecessary_typecast", "unused_typecasts"); - self.register_renamed("unsigned_negate", "unsigned_negation"); - self.register_renamed("type_limits", "unused_comparisons"); - self.register_renamed("type_overflow", "overflowing_literals"); - self.register_renamed("ctypes", "improper_ctypes"); - self.register_renamed("owned_heap_memory", "box_pointers"); - self.register_renamed("unused_attribute", "unused_attributes"); - self.register_renamed("path_statement", "path_statements"); - self.register_renamed("unused_result", "unused_results"); - self.register_renamed("non_uppercase_statics", "non_upper_case_globals"); - self.register_renamed("unnecessary_parens", "unused_parens"); - self.register_renamed("unnecessary_import_braces", "unused_import_braces"); - self.register_renamed("unsafe_block", "unsafe_blocks"); - self.register_renamed("unnecessary_allocation", "unused_allocation"); - self.register_renamed("missing_doc", "missing_docs"); - self.register_renamed("unused_extern_crate", "unused_extern_crates"); - self.register_renamed("unnecessary_qualification", "unused_qualifications"); - self.register_renamed("unrecognized_lint", "unknown_lints"); - self.register_renamed("unused_variable", "unused_variables"); - self.register_renamed("dead_assignment", "unused_assignments"); - self.register_renamed("unknown_crate_type", "unknown_crate_types"); - self.register_renamed("variant_size_difference", "variant_size_differences"); - self.register_renamed("transmute_fat_ptr", "fat_ptr_transmutes"); + // Insert temporary renamings for a one-time deprecation self.register_renamed("raw_pointer_deriving", "raw_pointer_derive"); } @@ -603,14 +580,6 @@ fn visit_foreign_item(&mut self, it: &ast::ForeignItem) { }) } - fn visit_view_item(&mut self, i: &ast::ViewItem) { - self.with_lint_attrs(&i.attrs[], |cx| { - run_lints!(cx, check_view_item, i); - cx.visit_ids(|v| v.visit_view_item(i)); - visit::walk_view_item(cx, i); - }) - } - fn visit_pat(&mut self, p: &ast::Pat) { run_lints!(self, check_pat, p); visit::walk_pat(self, p); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 826a35e3bb5..a4a3f485af1 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -128,7 +128,6 @@ pub trait LintPass { fn check_crate(&mut self, _: &Context, _: &ast::Crate) { } fn check_ident(&mut self, _: &Context, _: Span, _: ast::Ident) { } fn check_mod(&mut self, _: &Context, _: &ast::Mod, _: Span, _: ast::NodeId) { } - fn check_view_item(&mut self, _: &Context, _: &ast::ViewItem) { } fn check_foreign_item(&mut self, _: &Context, _: &ast::ForeignItem) { } fn check_item(&mut self, _: &Context, _: &ast::Item) { } fn check_local(&mut self, _: &Context, _: &ast::Local) { } diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 5de683f8a4f..7b71120ba64 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -40,10 +40,6 @@ pub struct CrateReader<'a> { } impl<'a, 'v> visit::Visitor<'v> for CrateReader<'a> { - fn visit_view_item(&mut self, a: &ast::ViewItem) { - self.process_view_item(a); - visit::walk_view_item(self, a); - } fn visit_item(&mut self, a: &ast::Item) { self.process_item(a); visit::walk_item(self, a); @@ -64,9 +60,8 @@ fn dump_crates(cstore: &CStore) { }) } -fn should_link(i: &ast::ViewItem) -> bool { +fn should_link(i: &ast::Item) -> bool { !attr::contains_name(&i.attrs[], "no_link") - } struct CrateInfo { @@ -181,29 +176,10 @@ fn process_crate(&self, c: &ast::Crate) { } } - fn process_view_item(&mut self, i: &ast::ViewItem) { - if !should_link(i) { - return; - } - - match self.extract_crate_info(i) { - Some(info) => { - let (cnum, _, _) = self.resolve_crate(&None, - &info.ident[], - &info.name[], - None, - i.span, - PathKind::Crate); - self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum); - } - None => () - } - } - - fn extract_crate_info(&self, i: &ast::ViewItem) -> Option { + fn extract_crate_info(&self, i: &ast::Item) -> Option { match i.node { - ast::ViewItemExternCrate(ident, ref path_opt, id) => { - let ident = token::get_ident(ident); + ast::ItemExternCrate(ref path_opt) => { + let ident = token::get_ident(i.ident); debug!("resolving extern crate stmt. ident: {} path_opt: {:?}", ident, path_opt); let name = match *path_opt { @@ -218,7 +194,7 @@ fn extract_crate_info(&self, i: &ast::ViewItem) -> Option { Some(CrateInfo { ident: ident.get().to_string(), name: name, - id: id, + id: i.id, should_link: should_link(i), }) } @@ -226,8 +202,26 @@ fn extract_crate_info(&self, i: &ast::ViewItem) -> Option { } } - fn process_item(&self, i: &ast::Item) { + fn process_item(&mut self, i: &ast::Item) { match i.node { + ast::ItemExternCrate(_) => { + if !should_link(i) { + return; + } + + match self.extract_crate_info(i) { + Some(info) => { + let (cnum, _, _) = self.resolve_crate(&None, + &info.ident[], + &info.name[], + None, + i.span, + PathKind::Crate); + self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum); + } + None => () + } + } ast::ItemForeignMod(ref fm) => { if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic { return; @@ -533,7 +527,7 @@ pub fn read_plugin_metadata<'b>(&'b mut self, #[derive(Copy)] pub enum CrateOrString<'a> { - Krate(&'a ast::ViewItem), + Krate(&'a ast::Item), Str(&'a str) } diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index a928d1c9022..7b7159da438 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -242,7 +242,7 @@ pub fn as_slice<'a>(&'a self) -> &'a [u8] { ((slice[2] as u32) << 8) | ((slice[3] as u32) << 0)) as uint; if len + 4 <= slice.len() { - slice.slice(4, len + 4) + &slice[4.. len + 4] } else { &[] // corrupt or old metadata } diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 6bf1798d246..1197276b990 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -74,7 +74,7 @@ fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64) -> Option { - // macros are encoded separately + ast::ItemExternCrate(_) | ast::ItemUse(_) |ast::ItemMac(..) => { + // these are encoded separately } } } diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 70b6ddf23fd..b1043a4152c 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -392,11 +392,11 @@ fn find_library_crate(&mut self) -> Option { }; let (hash, rlib) = if file.starts_with(&rlib_prefix[]) && file.ends_with(".rlib") { - (file.slice(rlib_prefix.len(), file.len() - ".rlib".len()), + (&file[(rlib_prefix.len()) .. (file.len() - ".rlib".len())], true) } else if file.starts_with(dylib_prefix.as_slice()) && file.ends_with(dypair.1.as_slice()) { - (file.slice(dylib_prefix.len(), file.len() - dypair.1.len()), + (&file[(dylib_prefix.len()) .. (file.len() - dypair.1.len())], false) } else { return FileDoesntMatch diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 5aacaa04e46..943be282103 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -243,19 +243,6 @@ fn parse_size(st: &mut PState) -> Option { } } -fn parse_trait_store_(st: &mut PState, conv: &mut F) -> ty::TraitStore where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - match next(st) { - '~' => ty::UniqTraitStore, - '&' => ty::RegionTraitStore(parse_region_(st, conv), parse_mutability(st)), - c => { - st.tcx.sess.bug(&format!("parse_trait_store(): bad input '{}'", - c)[]) - } - } -} - fn parse_vec_per_param_space<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, mut f: F) -> VecPerParamSpace where @@ -641,14 +628,6 @@ fn parse_abi_set(st: &mut PState) -> abi::Abi { }) } -fn parse_onceness(c: char) -> ast::Onceness { - match c { - 'o' => ast::Once, - 'm' => ast::Many, - _ => panic!("parse_onceness: bad onceness") - } -} - fn parse_closure_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F) -> ty::ClosureTy<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, @@ -661,16 +640,10 @@ fn parse_closure_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { let unsafety = parse_unsafety(next(st)); - let onceness = parse_onceness(next(st)); - let store = parse_trait_store_(st, conv); - let bounds = parse_existential_bounds_(st, conv); let sig = parse_sig_(st, conv); let abi = parse_abi_set(st); ty::ClosureTy { unsafety: unsafety, - onceness: onceness, - store: store, - bounds: bounds, sig: sig, abi: abi, } @@ -734,7 +707,7 @@ pub fn parse_def_id(buf: &[u8]) -> ast::DefId { } let crate_part = &buf[0u..colon_idx]; - let def_part = &buf[(colon_idx + 1u)..len]; + let def_part = &buf[colon_idx + 1u..len]; let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| s.parse::()) { Some(cn) => cn as ast::CrateNum, diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index bdd08ad6c49..9aead5bf4e7 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -305,17 +305,6 @@ pub fn enc_trait_ref<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, enc_substs(w, cx, s.substs); } -pub fn enc_trait_store(w: &mut SeekableMemWriter, cx: &ctxt, s: ty::TraitStore) { - match s { - ty::UniqTraitStore => mywrite!(w, "~"), - ty::RegionTraitStore(re, m) => { - mywrite!(w, "&"); - enc_region(w, cx, re); - enc_mutability(w, m); - } - } -} - fn enc_unsafety(w: &mut SeekableMemWriter, p: ast::Unsafety) { match p { ast::Unsafety::Normal => mywrite!(w, "n"), @@ -329,13 +318,6 @@ fn enc_abi(w: &mut SeekableMemWriter, abi: Abi) { mywrite!(w, "]") } -fn enc_onceness(w: &mut SeekableMemWriter, o: ast::Onceness) { - match o { - ast::Once => mywrite!(w, "o"), - ast::Many => mywrite!(w, "m") - } -} - pub fn enc_bare_fn_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, ft: &ty::BareFnTy<'tcx>) { enc_unsafety(w, ft.unsafety); @@ -346,9 +328,6 @@ pub fn enc_bare_fn_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, pub fn enc_closure_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, ft: &ty::ClosureTy<'tcx>) { enc_unsafety(w, ft.unsafety); - enc_onceness(w, ft.onceness); - enc_trait_store(w, cx, ft.store); - enc_existential_bounds(w, cx, &ft.bounds); enc_fn_sig(w, cx, &ft.sig); enc_abi(w, ft.abi); } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 550c0f34caf..537a2b3f545 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -332,8 +332,6 @@ fn fold_block(&mut self, blk: P) -> P { } }).collect(); let blk_sans_items = P(ast::Block { - view_items: Vec::new(), // I don't know if we need the view_items - // here, but it doesn't break tests! stmts: stmts_sans_items, expr: expr, id: id, @@ -515,17 +513,6 @@ fn tr(&self, dcx: &DecodeContext) -> ty::BoundRegion { } } -impl tr for ty::TraitStore { - fn tr(&self, dcx: &DecodeContext) -> ty::TraitStore { - match *self { - ty::RegionTraitStore(r, m) => { - ty::RegionTraitStore(r.tr(dcx), m) - } - ty::UniqTraitStore => ty::UniqTraitStore - } - } -} - // ______________________________________________________________________ // Encoding and decoding of freevar information diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index a1ac25a5650..1a2162b3076 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -424,7 +424,7 @@ fn expr(&mut self, expr: &ast::Expr, pred: CFGIndex) -> CFGIndex { } ast::ExprMethodCall(_, _, ref args) => { - self.call(expr, pred, &*args[0], args.slice_from(1).iter().map(|e| &**e)) + self.call(expr, pred, &*args[0], args[1..].iter().map(|e| &**e)) } ast::ExprIndex(ref l, ref r) | diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs index 1f779acac25..623f3525d4a 100644 --- a/src/librustc/middle/check_loop.rs +++ b/src/librustc/middle/check_loop.rs @@ -73,12 +73,12 @@ fn require_loop(&self, name: &str, span: Span) { match self.cx { Loop => {} Closure => { - self.sess.span_err(span, - &format!("`{}` inside of a closure", name)[]); + span_err!(self.sess, span, E0267, + "`{}` inside of a closure", name); } Normal => { - self.sess.span_err(span, - &format!("`{}` outside of loop", name)[]); + span_err!(self.sess, span, E0268, + "`{}` outside of loop", name); } } } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index a1a90395b3b..aa803d9d8ae 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -57,7 +57,7 @@ /// ++++++++++++++++++++++++++ /// + _ + [_, _, ..tail] + /// ++++++++++++++++++++++++++ -impl<'a> fmt::Show for Matrix<'a> { +impl<'a> fmt::Debug for Matrix<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "\n")); @@ -226,11 +226,10 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) { ast::ExprForLoop(ref pat, _, _, _) => { let mut static_inliner = StaticInliner::new(cx.tcx); is_refutable(cx, &*static_inliner.fold_pat((*pat).clone()), |uncovered_pat| { - cx.tcx.sess.span_err( - pat.span, - &format!("refutable pattern in `for` loop binding: \ + span_err!(cx.tcx.sess, pat.span, E0297, + "refutable pattern in `for` loop binding: \ `{}` not covered", - pat_to_string(uncovered_pat))[]); + pat_to_string(uncovered_pat)); }); // Check legality of move bindings. @@ -869,7 +868,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], Some(true) => Some(vec![]), Some(false) => None, None => { - cx.tcx.sess.span_err(pat_span, "mismatched types between arms"); + span_err!(cx.tcx.sess, pat_span, E0298, "mismatched types between arms"); None } } @@ -882,7 +881,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], Some(true) => Some(vec![]), Some(false) => None, None => { - cx.tcx.sess.span_err(pat_span, "mismatched types between arms"); + span_err!(cx.tcx.sess, pat_span, E0299, "mismatched types between arms"); None } } @@ -921,13 +920,13 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], } ast::PatMac(_) => { - cx.tcx.sess.span_err(pat_span, "unexpanded macro"); + span_err!(cx.tcx.sess, pat_span, E0300, "unexpanded macro"); None } }; head.map(|mut head| { head.push_all(&r[..col]); - head.push_all(&r[(col + 1)..]); + head.push_all(&r[col + 1..]); head }) } @@ -1082,11 +1081,8 @@ fn borrow(&mut self, _: LoanCause) { match kind { MutBorrow => { - self.cx - .tcx - .sess - .span_err(span, - "cannot mutably borrow in a pattern guard") + span_err!(self.cx.tcx.sess, span, E0301, + "cannot mutably borrow in a pattern guard") } ImmBorrow | UniqueImmBorrow => {} } @@ -1095,10 +1091,7 @@ fn decl_without_init(&mut self, _: NodeId, _: Span) {} fn mutate(&mut self, _: NodeId, span: Span, _: cmt, mode: MutateMode) { match mode { JustWrite | WriteAndRead => { - self.cx - .tcx - .sess - .span_err(span, "cannot assign in a pattern guard") + span_err!(self.cx.tcx.sess, span, E0302, "cannot assign in a pattern guard") } Init => {} } @@ -1120,7 +1113,7 @@ struct AtBindingPatternVisitor<'a, 'b:'a, 'tcx:'b> { impl<'a, 'b, 'tcx, 'v> Visitor<'v> for AtBindingPatternVisitor<'a, 'b, 'tcx> { fn visit_pat(&mut self, pat: &Pat) { if !self.bindings_allowed && pat_is_binding(&self.cx.tcx.def_map, pat) { - self.cx.tcx.sess.span_err(pat.span, + span_err!(self.cx.tcx.sess, pat.span, E0303, "pattern bindings are not allowed \ after an `@`"); } diff --git a/src/librustc/middle/check_static_recursion.rs b/src/librustc/middle/check_static_recursion.rs index 86a58dae45a..4280b7fe3f0 100644 --- a/src/librustc/middle/check_static_recursion.rs +++ b/src/librustc/middle/check_static_recursion.rs @@ -83,7 +83,7 @@ pub fn check_item_recursion<'a>(sess: &'a Session, impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> { fn visit_item(&mut self, it: &ast::Item) { if self.idstack.iter().any(|x| x == &(it.id)) { - self.sess.span_err(self.root_it.span, "recursive constant"); + span_err!(self.sess, self.root_it.span, E0265, "recursive constant"); return; } self.idstack.push(it.id); @@ -103,9 +103,9 @@ fn visit_expr(&mut self, e: &ast::Expr) { self.visit_item(item), ast_map::NodeForeignItem(_) => {}, _ => { - self.sess.span_err(e.span, - &format!("expected item, found {}", - self.ast_map.node_to_string(def_id.node))[]); + span_err!(self.sess, e.span, E0266, + "expected item, found {}", + self.ast_map.node_to_string(def_id.node)); return; }, } diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 2b9bd1cd09f..a1727869810 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -118,17 +118,17 @@ fn pre(&self, assert!(self.bits_per_id > 0); let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index); let (start, end) = self.compute_id_range(cfgidx); - let on_entry = self.on_entry.slice(start, end); + let on_entry = &self.on_entry[start.. end]; let entry_str = bits_to_string(on_entry); - let gens = self.gens.slice(start, end); + let gens = &self.gens[start.. end]; let gens_str = if gens.iter().any(|&u| u != 0) { format!(" gen: {}", bits_to_string(gens)) } else { "".to_string() }; - let kills = self.kills.slice(start, end); + let kills = &self.kills[start .. end]; let kills_str = if kills.iter().any(|&u| u != 0) { format!(" kill: {}", bits_to_string(kills)) } else { @@ -232,7 +232,7 @@ pub fn add_gen(&mut self, id: ast::NodeId, bit: uint) { let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index); let (start, end) = self.compute_id_range(cfgidx); - let gens = self.gens.slice_mut(start, end); + let gens = &mut self.gens[start.. end]; set_bit(gens, bit); } @@ -245,7 +245,7 @@ pub fn add_kill(&mut self, id: ast::NodeId, bit: uint) { let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index); let (start, end) = self.compute_id_range(cfgidx); - let kills = self.kills.slice_mut(start, end); + let kills = &mut self.kills[start.. end]; set_bit(kills, bit); } @@ -256,9 +256,9 @@ fn apply_gen_kill(&self, cfgidx: CFGIndex, bits: &mut [uint]) { assert!(self.bits_per_id > 0); let (start, end) = self.compute_id_range(cfgidx); - let gens = self.gens.slice(start, end); + let gens = &self.gens[start.. end]; bitwise(bits, gens, &Union); - let kills = self.kills.slice(start, end); + let kills = &self.kills[start.. end]; bitwise(bits, kills, &Subtract); debug!("{} apply_gen_kill(cfgidx={:?}, bits={}) [after]", @@ -304,7 +304,7 @@ pub fn each_bit_for_node(&self, e: EntryOrExit, cfgidx: CFGIndex, f: F) -> bo } let (start, end) = self.compute_id_range(cfgidx); - let on_entry = self.on_entry.slice(start, end); + let on_entry = &self.on_entry[start.. end]; let temp_bits; let slice = match e { Entry => on_entry, @@ -336,7 +336,7 @@ pub fn each_gen_bit(&self, id: ast::NodeId, f: F) -> bool where let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index); let (start, end) = self.compute_id_range(cfgidx); - let gens = self.gens.slice(start, end); + let gens = &self.gens[start.. end]; debug!("{} each_gen_bit(id={}, gens={})", self.analysis_name, id, bits_to_string(gens)); self.each_bit(gens, f) @@ -396,7 +396,7 @@ pub fn add_kills_from_flow_exits(&mut self, cfg: &cfg::CFG) { cfg.graph.each_edge(|_edge_index, edge| { let flow_exit = edge.source(); let (start, end) = self.compute_id_range(flow_exit); - let mut orig_kills = self.kills.slice(start, end).to_vec(); + let mut orig_kills = self.kills[start.. end].to_vec(); let mut changed = false; for &node_id in edge.data.exiting_scopes.iter() { @@ -404,7 +404,7 @@ pub fn add_kills_from_flow_exits(&mut self, cfg: &cfg::CFG) { match opt_cfg_idx { Some(cfg_idx) => { let (start, end) = self.compute_id_range(cfg_idx); - let kills = self.kills.slice(start, end); + let kills = &self.kills[start.. end]; if bitwise(orig_kills.as_mut_slice(), kills, &Union) { changed = true; } @@ -418,7 +418,7 @@ pub fn add_kills_from_flow_exits(&mut self, cfg: &cfg::CFG) { } if changed { - let bits = self.kills.slice_mut(start, end); + let bits = &mut self.kills[start.. end]; debug!("{} add_kills_from_flow_exits flow_exit={:?} bits={} [before]", self.analysis_name, flow_exit, mut_bits_to_string(bits)); bits.clone_from_slice(&orig_kills[]); @@ -487,7 +487,7 @@ fn walk_cfg(&mut self, let (start, end) = self.dfcx.compute_id_range(node_index); // Initialize local bitvector with state on-entry. - in_out.clone_from_slice(self.dfcx.on_entry.slice(start, end)); + in_out.clone_from_slice(&self.dfcx.on_entry[start.. end]); // Compute state on-exit by applying transfer function to // state on-entry. @@ -528,13 +528,13 @@ fn propagate_bits_into_entry_set_for(&mut self, let (start, end) = self.dfcx.compute_id_range(cfgidx); let changed = { // (scoping mutable borrow of self.dfcx.on_entry) - let on_entry = self.dfcx.on_entry.slice_mut(start, end); + let on_entry = &mut self.dfcx.on_entry[start.. end]; bitwise(on_entry, pred_bits, &self.dfcx.oper) }; if changed { debug!("{} changed entry set for {:?} to {}", self.dfcx.analysis_name, cfgidx, - bits_to_string(self.dfcx.on_entry.slice(start, end))); + bits_to_string(&self.dfcx.on_entry[start.. end])); self.changed = true; } } diff --git a/src/librustc/middle/graph.rs b/src/librustc/middle/graph.rs index 30e0ce33018..affeef330c4 100644 --- a/src/librustc/middle/graph.rs +++ b/src/librustc/middle/graph.rs @@ -32,7 +32,7 @@ #![allow(dead_code)] // still WIP -use std::fmt::{Formatter, Error, Show}; +use std::fmt::{Formatter, Error, Debug}; use std::uint; use std::collections::BitvSet; @@ -53,7 +53,7 @@ pub struct Edge { pub data: E, } -impl Show for Edge { +impl Debug for Edge { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { write!(f, "Edge {{ next_edge: [{:?}, {:?}], source: {:?}, target: {:?}, data: {:?} }}", self.next_edge[0], self.next_edge[1], self.source, @@ -353,7 +353,7 @@ pub fn target(&self) -> NodeIndex { #[cfg(test)] mod test { use middle::graph::*; - use std::fmt::Show; + use std::fmt::Debug; type TestNode = Node<&'static str>; type TestEdge = Edge<&'static str>; @@ -408,7 +408,7 @@ fn each_edge() { }); } - fn test_adjacent_edges(graph: &Graph, + fn test_adjacent_edges(graph: &Graph, start_index: NodeIndex, start_data: N, expected_incoming: &[(E,N)], diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs index 4a4328fa98b..3280769ff03 100644 --- a/src/librustc/middle/infer/combine.rs +++ b/src/librustc/middle/infer/combine.rs @@ -202,39 +202,6 @@ fn bare_fn_tys(&self, a: &ty::BareFnTy<'tcx>, sig: sig}) } - fn closure_tys(&self, a: &ty::ClosureTy<'tcx>, - b: &ty::ClosureTy<'tcx>) -> cres<'tcx, ty::ClosureTy<'tcx>> { - - let store = match (a.store, b.store) { - (ty::RegionTraitStore(a_r, a_m), - ty::RegionTraitStore(b_r, b_m)) if a_m == b_m => { - let r = try!(self.contraregions(a_r, b_r)); - ty::RegionTraitStore(r, a_m) - } - - _ if a.store == b.store => { - a.store - } - - _ => { - return Err(ty::terr_sigil_mismatch(expected_found(self, a.store, b.store))) - } - }; - let unsafety = try!(self.unsafeties(a.unsafety, b.unsafety)); - let onceness = try!(self.oncenesses(a.onceness, b.onceness)); - let bounds = try!(self.existential_bounds(&a.bounds, &b.bounds)); - let sig = try!(self.binders(&a.sig, &b.sig)); - let abi = try!(self.abi(a.abi, b.abi)); - Ok(ty::ClosureTy { - unsafety: unsafety, - onceness: onceness, - store: store, - bounds: bounds, - sig: sig, - abi: abi, - }) - } - fn fn_sigs(&self, a: &ty::FnSig<'tcx>, b: &ty::FnSig<'tcx>) -> cres<'tcx, ty::FnSig<'tcx>> { if a.variadic != b.variadic { return Err(ty::terr_variadic_mismatch(expected_found(self, a.variadic, b.variadic))); @@ -356,31 +323,6 @@ fn contraregions(&self, a: ty::Region, b: ty::Region) fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region>; - fn trait_stores(&self, - vk: ty::terr_vstore_kind, - a: ty::TraitStore, - b: ty::TraitStore) - -> cres<'tcx, ty::TraitStore> { - debug!("{}.trait_stores(a={:?}, b={:?})", self.tag(), a, b); - - match (a, b) { - (ty::RegionTraitStore(a_r, a_m), - ty::RegionTraitStore(b_r, b_m)) if a_m == b_m => { - self.contraregions(a_r, b_r).and_then(|r| { - Ok(ty::RegionTraitStore(r, a_m)) - }) - } - - _ if a == b => { - Ok(a) - } - - _ => { - Err(ty::terr_trait_stores_differ(vk, expected_found(self, a, b))) - } - } - } - fn trait_refs(&self, a: &ty::TraitRef<'tcx>, b: &ty::TraitRef<'tcx>) diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 1b9d6ec6c33..18c36f870b5 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -371,12 +371,11 @@ fn report_type_error(&self, trace: TypeTrace<'tcx>, terr: &ty::type_err<'tcx>) { infer::EquatePredicate(_) => "equality predicate not satisfied", }; - self.tcx.sess.span_err( - trace.origin.span(), - &format!("{}: {} ({})", + span_err!(self.tcx.sess, trace.origin.span(), E0308, + "{}: {} ({})", message_root_str, expected_found_str, - ty::type_err_to_str(self.tcx, terr))[]); + ty::type_err_to_str(self.tcx, terr)); match trace.origin { infer::MatchExpressionArm(_, arm_span) => @@ -443,9 +442,8 @@ fn report_generic_bound_failure(&self, match sub { ty::ReFree(ty::FreeRegion {bound_region: ty::BrNamed(..), ..}) => { // Does the required lifetime have a nice name we can print? - self.tcx.sess.span_err( - origin.span(), - &format!("{} may not live long enough", labeled_user_string)[]); + span_err!(self.tcx.sess, origin.span(), E0309, + "{} may not live long enough", labeled_user_string); self.tcx.sess.span_help( origin.span(), &format!( @@ -456,9 +454,8 @@ fn report_generic_bound_failure(&self, ty::ReStatic => { // Does the required lifetime have a nice name we can print? - self.tcx.sess.span_err( - origin.span(), - &format!("{} may not live long enough", labeled_user_string)[]); + span_err!(self.tcx.sess, origin.span(), E0310, + "{} may not live long enough", labeled_user_string); self.tcx.sess.span_help( origin.span(), &format!( @@ -468,11 +465,9 @@ fn report_generic_bound_failure(&self, _ => { // If not, be less specific. - self.tcx.sess.span_err( - origin.span(), - &format!( + span_err!(self.tcx.sess, origin.span(), E0311, "{} may not live long enough", - labeled_user_string)[]); + labeled_user_string); self.tcx.sess.span_help( origin.span(), &format!( @@ -499,8 +494,7 @@ fn report_concrete_failure(&self, self.report_and_explain_type_error(trace, &terr); } infer::Reborrow(span) => { - self.tcx.sess.span_err( - span, + span_err!(self.tcx.sess, span, E0312, "lifetime of reference outlines \ lifetime of borrowed content..."); note_and_explain_region( @@ -515,14 +509,13 @@ fn report_concrete_failure(&self, ""); } infer::ReborrowUpvar(span, ref upvar_id) => { - self.tcx.sess.span_err( - span, - &format!("lifetime of borrowed pointer outlives \ + span_err!(self.tcx.sess, span, E0313, + "lifetime of borrowed pointer outlives \ lifetime of captured variable `{}`...", ty::local_var_name_str(self.tcx, upvar_id.var_id) .get() - .to_string())[]); + .to_string()); note_and_explain_region( self.tcx, "...the borrowed pointer is valid for ", @@ -539,8 +532,7 @@ fn report_concrete_failure(&self, ""); } infer::InfStackClosure(span) => { - self.tcx.sess.span_err( - span, + span_err!(self.tcx.sess, span, E0314, "closure outlives stack frame"); note_and_explain_region( self.tcx, @@ -554,8 +546,7 @@ fn report_concrete_failure(&self, ""); } infer::InvokeClosure(span) => { - self.tcx.sess.span_err( - span, + span_err!(self.tcx.sess, span, E0315, "cannot invoke closure outside of its lifetime"); note_and_explain_region( self.tcx, diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs index 0f487fffe5c..9339f435d8f 100644 --- a/src/librustc/middle/infer/region_inference/mod.rs +++ b/src/librustc/middle/infer/region_inference/mod.rs @@ -609,8 +609,7 @@ pub fn combine_vars(&self, pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot) -> Vec { - self.undo_log.borrow() - .slice_from(mark.length) + self.undo_log.borrow()[mark.length..] .iter() .filter_map(|&elt| match elt { AddVar(vid) => Some(vid), @@ -637,7 +636,7 @@ pub fn tainted(&self, mark: &RegionSnapshot, r0: Region) -> Vec { debug!("result_index={}, r={:?}", result_index, r); for undo_entry in - self.undo_log.borrow().slice_from(mark.length).iter() + self.undo_log.borrow()[mark.length..].iter() { match undo_entry { &AddConstraint(ConstrainVarSubVar(a, b)) => { diff --git a/src/librustc/middle/infer/unify.rs b/src/librustc/middle/infer/unify.rs index 4fa8e07ddd4..ed11cafdca9 100644 --- a/src/librustc/middle/infer/unify.rs +++ b/src/librustc/middle/infer/unify.rs @@ -17,7 +17,7 @@ use middle::infer::{uok, ures}; use middle::infer::InferCtxt; use std::cell::RefCell; -use std::fmt::Show; +use std::fmt::Debug; use syntax::ast; use util::ppaux::Repr; use util::snapshot_vec as sv; @@ -32,7 +32,7 @@ /// (possibly not yet known) sort of integer. /// /// Implementations of this trait are at the end of this file. -pub trait UnifyKey<'tcx, V> : Clone + Show + PartialEq + Repr<'tcx> { +pub trait UnifyKey<'tcx, V> : Clone + Debug + PartialEq + Repr<'tcx> { fn index(&self) -> uint; fn from_index(u: uint) -> Self; diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index ff79ace9924..2c0de9d1634 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -320,9 +320,7 @@ pub fn collect_language_items(krate: &ast::Crate, ContravariantLifetimeItem, "contravariant_lifetime", contravariant_lifetime; InvariantLifetimeItem, "invariant_lifetime", invariant_lifetime; - NoSendItem, "no_send_bound", no_send_bound; NoCopyItem, "no_copy_bound", no_copy_bound; - NoSyncItem, "no_sync_bound", no_sync_bound; ManagedItem, "managed_bound", managed_bound; NonZeroItem, "non_zero", non_zero; diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 27a0324a3c4..43989d0aadc 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -198,13 +198,13 @@ pub fn check_crate(tcx: &ty::ctxt) { tcx.sess.abort_if_errors(); } -impl fmt::Show for LiveNode { +impl fmt::Debug for LiveNode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "ln({})", self.get()) } } -impl fmt::Show for Variable { +impl fmt::Debug for Variable { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "v({})", self.get()) } @@ -1557,8 +1557,7 @@ fn check_ret(&self, }, _ => false }; - self.ir.tcx.sess.span_err( - sp, "not all control paths return a value"); + span_err!(self.ir.tcx.sess, sp, E0269, "not all control paths return a value"); if ends_with_stmt { let last_stmt = body.stmts.first().unwrap(); let original_span = original_sp(self.ir.tcx.sess.codemap(), @@ -1575,7 +1574,7 @@ fn check_ret(&self, } ty::FnDiverging if self.live_on_entry(entry_ln, self.s.clean_exit_var).is_some() => { - self.ir.tcx.sess.span_err(sp, + span_err!(self.ir.tcx.sess, sp, E0270, "computation may converge in a function marked as diverging"); } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index d6e652f16c6..b93cde4bf64 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -297,6 +297,7 @@ fn propagate_node(&mut self, node: &ast_map::Node, // These are normal, nothing reachable about these // inherently and their children are already in the // worklist, as determined by the privacy pass + ast::ItemExternCrate(_) | ast::ItemUse(_) | ast::ItemTy(..) | ast::ItemStatic(_, _, _) | ast::ItemMod(..) | ast::ItemForeignMod(..) | ast::ItemImpl(..) | ast::ItemTrait(..) | diff --git a/src/librustc/middle/recursion_limit.rs b/src/librustc/middle/recursion_limit.rs index 017641bd3b7..81cbdf13c51 100644 --- a/src/librustc/middle/recursion_limit.rs +++ b/src/librustc/middle/recursion_limit.rs @@ -33,7 +33,7 @@ pub fn update_recursion_limit(sess: &Session, krate: &ast::Crate) { } } - sess.span_err(attr.span, "malformed recursion limit attribute, \ + span_err!(sess, attr.span, E0296, "malformed recursion limit attribute, \ expected #![recursion_limit=\"N\"]"); } } diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 90ba442ee39..b4b2e1b63e8 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -22,9 +22,6 @@ use util::common::can_reach; use std::cell::RefCell; -// NOTE(stage0) remove import after a snapshot -#[cfg(stage0)] -use std::hash::{Hash}; use syntax::codemap::Span; use syntax::{ast, visit}; use syntax::ast::{Block, Item, FnDecl, NodeId, Arm, Pat, Stmt, Expr, Local}; diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index eff0018becc..030bf26699f 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -94,6 +94,8 @@ fn visit_item(&mut self, item: &ast::Item) { // Fn lifetimes get added in visit_fn below: visit::walk_item(this, item); } + ast::ItemExternCrate(_) | + ast::ItemUse(_) | ast::ItemMod(..) | ast::ItemMac(..) | ast::ItemForeignMod(..) | @@ -396,10 +398,9 @@ fn resolve_free_lifetime_ref(&mut self, } fn unresolved_lifetime_ref(&self, lifetime_ref: &ast::Lifetime) { - self.sess.span_err( - lifetime_ref.span, - &format!("use of undeclared lifetime name `{}`", - token::get_name(lifetime_ref.name))[]); + span_err!(self.sess, lifetime_ref.span, E0261, + "use of undeclared lifetime name `{}`", + token::get_name(lifetime_ref.name)); } fn check_lifetime_defs(&mut self, old_scope: Scope, lifetimes: &Vec) { @@ -409,11 +410,9 @@ fn check_lifetime_defs(&mut self, old_scope: Scope, lifetimes: &Vec, } } -impl<'a> fmt::Show for ScopeChain<'a> { +impl<'a> fmt::Debug for ScopeChain<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { match *self { EarlyScope(space, defs, _) => write!(fmt, "EarlyScope({:?}, {:?})", space, defs), diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index 9ad2dd499cc..889d8b4052f 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -238,7 +238,7 @@ pub struct SeparateVecsPerParamSpace { pub fns: Vec, } -impl fmt::Show for VecPerParamSpace { +impl fmt::Debug for VecPerParamSpace { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { try!(write!(fmt, "VecPerParamSpace {{")); for space in ParamSpace::all().iter() { @@ -373,12 +373,12 @@ pub fn is_empty_in(&self, space: ParamSpace) -> bool { pub fn get_slice<'a>(&'a self, space: ParamSpace) -> &'a [T] { let (start, limit) = self.limits(space); - self.content.slice(start, limit) + &self.content[start.. limit] } pub fn get_mut_slice<'a>(&'a mut self, space: ParamSpace) -> &'a mut [T] { let (start, limit) = self.limits(space); - self.content.slice_mut(start, limit) + &mut self.content[start.. limit] } pub fn opt_get<'a>(&'a self, diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs index 6d0e60ec495..7ccb5e6e711 100644 --- a/src/librustc/middle/traits/error_reporting.rs +++ b/src/librustc/middle/traits/error_reporting.rs @@ -55,12 +55,10 @@ pub fn report_projection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, let predicate = infcx.resolve_type_vars_if_possible(&obligation.predicate); if !predicate.references_error() { - infcx.tcx.sess.span_err( - obligation.cause.span, - format!( + span_err!(infcx.tcx.sess, obligation.cause.span, E0271, "type mismatch resolving `{}`: {}", predicate.user_string(infcx.tcx), - ty::type_err_to_str(infcx.tcx, &error.err)).as_slice()); + ty::type_err_to_str(infcx.tcx, &error.err)); note_obligation_cause(infcx, obligation); } } @@ -97,28 +95,25 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, Position::ArgumentNamed(s) => match generic_map.get(s) { Some(val) => Some(val.as_slice()), None => { - infcx.tcx.sess - .span_err(err_sp, - format!("the #[rustc_on_unimplemented] \ + span_err!(infcx.tcx.sess, err_sp, E0272, + "the #[rustc_on_unimplemented] \ attribute on \ trait definition for {} refers to \ non-existent type parameter {}", - trait_str, s) - .as_slice()); + trait_str, s); errored = true; None } }, _ => { - infcx.tcx.sess - .span_err(err_sp, - format!("the #[rustc_on_unimplemented] \ + span_err!(infcx.tcx.sess, err_sp, E0273, + "the #[rustc_on_unimplemented] \ attribute on \ trait definition for {} must have named \ format arguments, \ eg `#[rustc_on_unimplemented = \ \"foo {{T}}\"]`", - trait_str).as_slice()); + trait_str); errored = true; None } @@ -130,11 +125,11 @@ trait definition for {} must have named \ report = Some(err); } } else { - infcx.tcx.sess.span_err(err_sp, - format!("the #[rustc_on_unimplemented] attribute on \ + span_err!(infcx.tcx.sess, err_sp, E0274, + "the #[rustc_on_unimplemented] attribute on \ trait definition for {} must have a value, \ eg `#[rustc_on_unimplemented = \"foo\"]`", - trait_str).as_slice()); + trait_str); } break; } @@ -151,11 +146,9 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, // We could track the stack here more precisely if we wanted, I imagine. let predicate = infcx.resolve_type_vars_if_possible(&obligation.predicate); - infcx.tcx.sess.span_err( - obligation.cause.span, - format!( + span_err!(infcx.tcx.sess, obligation.cause.span, E0275, "overflow evaluating the requirement `{}`", - predicate.user_string(infcx.tcx)).as_slice()); + predicate.user_string(infcx.tcx)); suggest_new_overflow_limit(infcx.tcx, obligation.cause.span); @@ -165,12 +158,10 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, SelectionError::Unimplemented => { match &obligation.cause.code { &ObligationCauseCode::CompareImplMethodObligation => { - infcx.tcx.sess.span_err( - obligation.cause.span, - format!( + span_err!(infcx.tcx.sess, obligation.cause.span, E0276, "the requirement `{}` appears on the impl \ method but not on the corresponding trait method", - obligation.predicate.user_string(infcx.tcx)).as_slice()); + obligation.predicate.user_string(infcx.tcx));; } _ => { match obligation.predicate { @@ -180,12 +171,10 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, if !trait_predicate.references_error() { let trait_ref = trait_predicate.to_poly_trait_ref(); - infcx.tcx.sess.span_err( - obligation.cause.span, - format!( + span_err!(infcx.tcx.sess, obligation.cause.span, E0277, "the trait `{}` is not implemented for the type `{}`", trait_ref.user_string(infcx.tcx), - trait_ref.self_ty().user_string(infcx.tcx)).as_slice()); + trait_ref.self_ty().user_string(infcx.tcx)); // Check if it has a custom "#[rustc_on_unimplemented]" // error message, report with that message if it does let custom_note = report_on_unimplemented(infcx, &*trait_ref.0, @@ -200,35 +189,29 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, ty::Predicate::Equate(ref predicate) => { let predicate = infcx.resolve_type_vars_if_possible(predicate); let err = infcx.equality_predicate(obligation.cause.span, - &predicate).unwrap_err(); - infcx.tcx.sess.span_err( - obligation.cause.span, - format!( + &predicate).err().unwrap(); + span_err!(infcx.tcx.sess, obligation.cause.span, E0278, "the requirement `{}` is not satisfied (`{}`)", predicate.user_string(infcx.tcx), - ty::type_err_to_str(infcx.tcx, &err)).as_slice()); + ty::type_err_to_str(infcx.tcx, &err)); } ty::Predicate::RegionOutlives(ref predicate) => { let predicate = infcx.resolve_type_vars_if_possible(predicate); let err = infcx.region_outlives_predicate(obligation.cause.span, - &predicate).unwrap_err(); - infcx.tcx.sess.span_err( - obligation.cause.span, - format!( + &predicate).err().unwrap(); + span_err!(infcx.tcx.sess, obligation.cause.span, E0279, "the requirement `{}` is not satisfied (`{}`)", predicate.user_string(infcx.tcx), - ty::type_err_to_str(infcx.tcx, &err)).as_slice()); + ty::type_err_to_str(infcx.tcx, &err)); } ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => { let predicate = infcx.resolve_type_vars_if_possible(&obligation.predicate); - infcx.tcx.sess.span_err( - obligation.cause.span, - format!( + span_err!(infcx.tcx.sess, obligation.cause.span, E0280, "the requirement `{}` is not satisfied", - predicate.user_string(infcx.tcx)).as_slice()); + predicate.user_string(infcx.tcx)); } } } @@ -239,15 +222,13 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, let expected_trait_ref = infcx.resolve_type_vars_if_possible(&*expected_trait_ref); let actual_trait_ref = infcx.resolve_type_vars_if_possible(&*actual_trait_ref); if !ty::type_is_error(actual_trait_ref.self_ty()) { - infcx.tcx.sess.span_err( - obligation.cause.span, - format!( + span_err!(infcx.tcx.sess, obligation.cause.span, E0281, "type mismatch: the type `{}` implements the trait `{}`, \ but the trait `{}` is required ({})", expected_trait_ref.self_ty().user_string(infcx.tcx), expected_trait_ref.user_string(infcx.tcx), actual_trait_ref.user_string(infcx.tcx), - ty::type_err_to_str(infcx.tcx, e)).as_slice()); + ty::type_err_to_str(infcx.tcx, e)); note_obligation_cause(infcx, obligation); } } @@ -293,18 +274,14 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, infcx.tcx.lang_items.sized_trait() .map_or(false, |sized_id| sized_id == trait_ref.def_id()) { - infcx.tcx.sess.span_err( - obligation.cause.span, - format!( + span_err!(infcx.tcx.sess, obligation.cause.span, E0282, "unable to infer enough type information about `{}`; \ type annotations required", - self_ty.user_string(infcx.tcx)).as_slice()); + self_ty.user_string(infcx.tcx)); } else { - infcx.tcx.sess.span_err( - obligation.cause.span, - format!( + span_err!(infcx.tcx.sess, obligation.cause.span, E0283, "type annotations required: cannot resolve `{}`", - predicate.user_string(infcx.tcx)).as_slice()); + predicate.user_string(infcx.tcx));; note_obligation_cause(infcx, obligation); } } @@ -323,11 +300,9 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, _ => { if !infcx.tcx.sess.has_errors() { - infcx.tcx.sess.span_err( - obligation.cause.span, - format!( + span_err!(infcx.tcx.sess, obligation.cause.span, E0284, "type annotations required: cannot resolve `{}`", - predicate.user_string(infcx.tcx)).as_slice()); + predicate.user_string(infcx.tcx));; note_obligation_cause(infcx, obligation); } } diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index 42624555ae4..568286e39d5 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -84,6 +84,7 @@ pub struct FulfillmentContext<'tcx> { region_obligations: NodeMap>>, } +#[derive(Clone)] pub struct RegionObligation<'tcx> { pub sub_region: ty::Region, pub sup_type: Ty<'tcx>, diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 425765edf87..89459f95b87 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -379,11 +379,10 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, false } Err(Overflow) => { - infcx.tcx.sess.span_err( - span, - format!("overflow evaluating whether `{}` is `{}`", - ty.user_string(infcx.tcx), - bound.user_string(infcx.tcx)).as_slice()); + span_err!(infcx.tcx.sess, span, E0285, + "overflow evaluating whether `{}` is `{}`", + ty.user_string(infcx.tcx), + bound.user_string(infcx.tcx)); suggest_new_overflow_limit(infcx.tcx, span); false } diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 62649653a69..e8d82150ade 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -1554,10 +1554,7 @@ fn nominal<'cx, 'tcx>(this: &mut SelectionContext<'cx, 'tcx>, let tcx = this.tcx(); match bound { ty::BoundSend => { - if - Some(def_id) == tcx.lang_items.no_send_bound() || - Some(def_id) == tcx.lang_items.managed_bound() - { + if Some(def_id) == tcx.lang_items.managed_bound() { return Err(Unimplemented) } } @@ -1568,7 +1565,6 @@ fn nominal<'cx, 'tcx>(this: &mut SelectionContext<'cx, 'tcx>, ty::BoundSync => { if - Some(def_id) == tcx.lang_items.no_sync_bound() || Some(def_id) == tcx.lang_items.managed_bound() || Some(def_id) == tcx.lang_items.unsafe_type() { diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index fe8362223e3..bdf9b16f139 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -236,13 +236,13 @@ pub fn fresh_substs_for_impl<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, infcx.fresh_substs_for_generics(span, &impl_generics) } -impl<'tcx, N> fmt::Show for VtableImplData<'tcx, N> { +impl<'tcx, N> fmt::Debug for VtableImplData<'tcx, N> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "VtableImpl({:?})", self.impl_def_id) } } -impl<'tcx> fmt::Show for super::VtableObjectData<'tcx> { +impl<'tcx> fmt::Debug for super::VtableObjectData<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "VtableObject(...)") } @@ -449,7 +449,7 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { } } -impl<'tcx> fmt::Show for super::FulfillmentErrorCode<'tcx> { +impl<'tcx> fmt::Debug for super::FulfillmentErrorCode<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { super::CodeSelectionError(ref e) => write!(f, "{:?}", e), @@ -465,7 +465,7 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { } } -impl<'tcx> fmt::Show for super::MismatchedProjectionTypes<'tcx> { +impl<'tcx> fmt::Debug for super::MismatchedProjectionTypes<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "MismatchedProjectionTypes(..)") } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index be6c6b9d34f..83bbdf14e4a 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -17,7 +17,6 @@ pub use self::InferRegion::*; pub use self::ImplOrTraitItemId::*; pub use self::UnboxedClosureKind::*; -pub use self::TraitStore::*; pub use self::ast_ty_to_ty_cache_entry::*; pub use self::Variance::*; pub use self::AutoAdjustment::*; @@ -61,7 +60,7 @@ use middle::ty_fold::{self, TypeFoldable, TypeFolder}; use middle::ty_walk::TypeWalker; use util::ppaux::{note_and_explain_region, bound_region_ptr_to_string}; -use util::ppaux::{trait_store_to_string, ty_to_string}; +use util::ppaux::ty_to_string; use util::ppaux::{Repr, UserString}; use util::common::{memoized, ErrorReported}; use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet}; @@ -70,7 +69,7 @@ use arena::TypedArena; use std::borrow::{BorrowFrom, Cow}; use std::cell::{Cell, RefCell}; -use std::cmp::{self, Ordering}; +use std::cmp; use std::fmt::{self, Show}; use std::hash::{Hash, Writer, SipHasher, Hasher}; use std::mem; @@ -247,14 +246,6 @@ pub struct mt<'tcx> { pub mutbl: ast::Mutability, } -#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Show)] -pub enum TraitStore { - /// Box - UniqTraitStore, - /// &Trait and &mut Trait - RegionTraitStore(Region, ast::Mutability), -} - #[derive(Clone, Copy, Show)] pub struct field_ty { pub name: Name, @@ -934,7 +925,7 @@ pub struct TyS<'tcx> { region_depth: u32, } -impl fmt::Show for TypeFlags { +impl fmt::Debug for TypeFlags { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.bits) } @@ -1041,11 +1032,8 @@ pub struct BareFnTy<'tcx> { #[derive(Clone, PartialEq, Eq, Hash, Show)] pub struct ClosureTy<'tcx> { pub unsafety: ast::Unsafety, - pub onceness: ast::Onceness, - pub store: TraitStore, - pub bounds: ExistentialBounds<'tcx>, - pub sig: PolyFnSig<'tcx>, pub abi: abi::Abi, + pub sig: PolyFnSig<'tcx>, } #[derive(Clone, Copy, PartialEq, Eq, Hash, Show)] @@ -1545,7 +1533,6 @@ pub enum type_err<'tcx> { terr_onceness_mismatch(expected_found), terr_abi_mismatch(expected_found), terr_mutability, - terr_sigil_mismatch(expected_found), terr_box_mutability, terr_ptr_mutability, terr_ref_mutability, @@ -1559,7 +1546,6 @@ pub enum type_err<'tcx> { terr_regions_no_overlap(Region, Region), terr_regions_insufficiently_polymorphic(BoundRegion, Region), terr_regions_overly_polymorphic(BoundRegion, Region), - terr_trait_stores_differ(terr_vstore_kind, expected_found), terr_sorts(expected_found>), terr_integer_as_char, terr_int_mismatch(expected_found), @@ -1703,37 +1689,37 @@ fn ne(&self, other: &InferRegion) -> bool { } } -impl fmt::Show for TyVid { +impl fmt::Debug for TyVid { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result{ write!(f, "_#{}t", self.index) } } -impl fmt::Show for IntVid { +impl fmt::Debug for IntVid { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "_#{}i", self.index) } } -impl fmt::Show for FloatVid { +impl fmt::Debug for FloatVid { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "_#{}f", self.index) } } -impl fmt::Show for RegionVid { +impl fmt::Debug for RegionVid { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "'_#{}r", self.index) } } -impl<'tcx> fmt::Show for FnSig<'tcx> { +impl<'tcx> fmt::Debug for FnSig<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "({:?}; variadic: {})->{:?}", self.inputs, self.variadic, self.output) } } -impl fmt::Show for InferTy { +impl fmt::Debug for InferTy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { TyVar(ref v) => v.fmt(f), @@ -1745,7 +1731,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::Show for IntVarValue { +impl fmt::Debug for IntVarValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { IntType(ref v) => v.fmt(f), @@ -3319,7 +3305,7 @@ fn sub(self, other: TypeContents) -> TypeContents { } } -impl fmt::Show for TypeContents { +impl fmt::Debug for TypeContents { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "TypeContents({:b})", self.bits) } @@ -4194,19 +4180,6 @@ pub fn ty_fn_args<'tcx>(fty: Ty<'tcx>) -> ty::Binder>> { ty_fn_sig(fty).inputs() } -pub fn ty_closure_store(fty: Ty) -> TraitStore { - match fty.sty { - ty_unboxed_closure(..) => { - // Close enough for the purposes of all the callers of this - // function (which is soon to be deprecated anyhow). - UniqTraitStore - } - ref s => { - panic!("ty_closure_store() called on non-closure type: {:?}", s) - } - } -} - pub fn ty_fn_ret<'tcx>(fty: Ty<'tcx>) -> Binder> { match fty.sty { ty_bare_fn(_, ref f) => f.sig.output(), @@ -4751,13 +4724,6 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { /// afterwards to present additional details, particularly when it comes to lifetime-related /// errors. pub fn type_err_to_str<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>) -> String { - fn tstore_to_closure(s: &TraitStore) -> String { - match s { - &UniqTraitStore => "proc".to_string(), - &RegionTraitStore(..) => "closure".to_string() - } - } - match *err { terr_cyclic_ty => "cyclic type of infinite size".to_string(), terr_mismatch => "types differ".to_string(), @@ -4776,11 +4742,6 @@ fn tstore_to_closure(s: &TraitStore) -> String { values.expected, values.found) } - terr_sigil_mismatch(values) => { - format!("expected {}, found {}", - tstore_to_closure(&values.expected), - tstore_to_closure(&values.found)) - } terr_mutability => "values differ in mutability".to_string(), terr_box_mutability => { "boxed values differ in mutability".to_string() @@ -4828,11 +4789,6 @@ fn tstore_to_closure(s: &TraitStore) -> String { found bound lifetime parameter {}", bound_region_ptr_to_string(cx, br)) } - terr_trait_stores_differ(_, ref values) => { - format!("trait storage differs: expected `{}`, found `{}`", - trait_store_to_string(cx, (*values).expected), - trait_store_to_string(cx, (*values).found)) - } terr_sorts(values) => { // A naive approach to making sure that we're not reporting silly errors such as: // (expected closure, found closure). @@ -5089,25 +5045,6 @@ pub fn associated_type_parameter_index(cx: &ctxt, cx.sess.bug("couldn't find associated type parameter index") } -#[derive(Copy, PartialEq, Eq)] -pub struct AssociatedTypeInfo { - pub def_id: ast::DefId, - pub index: uint, - pub name: ast::Name, -} - -impl PartialOrd for AssociatedTypeInfo { - fn partial_cmp(&self, other: &AssociatedTypeInfo) -> Option { - Some(self.index.cmp(&other.index)) - } -} - -impl Ord for AssociatedTypeInfo { - fn cmp(&self, other: &AssociatedTypeInfo) -> Ordering { - self.index.cmp(&other.index) - } -} - pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId) -> Rc> { lookup_locally_or_in_crate_store("trait_item_def_ids", @@ -5369,15 +5306,13 @@ pub fn enum_variants<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) discriminant = val as Disr } Ok(_) => { - cx.sess - .span_err(e.span, + span_err!(cx.sess, e.span, E0304, "expected signed integer constant"); } Err(ref err) => { - cx.sess - .span_err(e.span, - &format!("expected constant: {}", - *err)[]); + span_err!(cx.sess, e.span, E0305, + "expected constant: {}", + *err); } }, None => {} @@ -5851,9 +5786,9 @@ pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> uint { const_eval::const_binary(_) => "binary array" }; - tcx.sess.span_err(count_expr.span, &format!( + span_err!(tcx.sess, count_expr.span, E0306, "expected positive integer for repeat count, found {}", - found)[]); + found); } Err(_) => { let found = match count_expr.node { @@ -5866,9 +5801,9 @@ pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> uint { _ => "non-constant expression" }; - tcx.sess.span_err(count_expr.span, &format!( + span_err!(tcx.sess, count_expr.span, E0307, "expected constant integer for repeat count, found {}", - found)[]); + found); } } 0 @@ -7338,11 +7273,8 @@ fn references_error(&self) -> bool { impl<'tcx> Repr<'tcx> for ClosureTy<'tcx> { fn repr(&self, tcx: &ctxt<'tcx>) -> String { - format!("ClosureTy({},{},{:?},{},{},{})", + format!("ClosureTy({},{},{})", self.unsafety, - self.onceness, - self.store, - self.bounds.repr(tcx), self.sig.repr(tcx), self.abi) } @@ -7373,5 +7305,5 @@ fn repr(&self, tcx: &ctxt<'tcx>) -> String { self.free_substs.repr(tcx), self.implicit_region_bound.repr(tcx), self.caller_bounds.repr(tcx)) - } } +} diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 37886b4a1e1..b4e6cff954b 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -124,10 +124,6 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region { r } - fn fold_trait_store(&mut self, s: ty::TraitStore) -> ty::TraitStore { - super_fold_trait_store(self, s) - } - fn fold_existential_bounds(&mut self, s: &ty::ExistentialBounds<'tcx>) -> ty::ExistentialBounds<'tcx> { super_fold_existential_bounds(self, s) @@ -225,12 +221,6 @@ fn fold_with>(&self, folder: &mut F) -> VecPerParamSpace } } -impl<'tcx> TypeFoldable<'tcx> for ty::TraitStore { - fn fold_with>(&self, folder: &mut F) -> ty::TraitStore { - folder.fold_trait_store(*self) - } -} - impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { fn fold_with>(&self, folder: &mut F) -> Ty<'tcx> { folder.fold_ty(*self) @@ -699,11 +689,8 @@ pub fn super_fold_closure_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T, -> ty::ClosureTy<'tcx> { ty::ClosureTy { - store: fty.store.fold_with(this), sig: fty.sig.fold_with(this), unsafety: fty.unsafety, - onceness: fty.onceness, - bounds: fty.bounds.fold_with(this), abi: fty.abi, } } @@ -726,17 +713,6 @@ pub fn super_fold_mt<'tcx, T: TypeFolder<'tcx>>(this: &mut T, mutbl: mt.mutbl} } -pub fn super_fold_trait_store<'tcx, T: TypeFolder<'tcx>>(this: &mut T, - trait_store: ty::TraitStore) - -> ty::TraitStore { - match trait_store { - ty::UniqTraitStore => ty::UniqTraitStore, - ty::RegionTraitStore(r, m) => { - ty::RegionTraitStore(r.fold_with(this), m) - } - } -} - pub fn super_fold_existential_bounds<'tcx, T: TypeFolder<'tcx>>( this: &mut T, bounds: &ty::ExistentialBounds<'tcx>) diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index 892a8004fec..25cca98c5fb 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -99,9 +99,9 @@ fn register(&mut self, name: &str, span: Span) { self.items.missing.push(lang_items::$item); } } else)* { - self.sess.span_err(span, - format!("unknown external lang item: `{}`", - name).as_slice()); + span_err!(self.sess, span, E0264, + "unknown external lang item: `{}`", + name); } } } diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs index ef8a89c40fb..c420d1f15b4 100644 --- a/src/librustc/plugin/load.rs +++ b/src/librustc/plugin/load.rs @@ -73,8 +73,10 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate, // We need to error on `#[macro_use] extern crate` when it isn't at the // crate root, because `$crate` won't work properly. Identify these by // spans, because the crate map isn't set up yet. - for vi in krate.module.view_items.iter() { - loader.span_whitelist.insert(vi.span); + for item in krate.module.items.iter() { + if let ast::ItemExternCrate(_) = item.node { + loader.span_whitelist.insert(item.span); + } } visit::walk_crate(&mut loader, krate); @@ -91,18 +93,21 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate, // note that macros aren't expanded yet, and therefore macros can't add plugins. impl<'a, 'v> Visitor<'v> for PluginLoader<'a> { - fn visit_view_item(&mut self, vi: &ast::ViewItem) { + fn visit_item(&mut self, item: &ast::Item) { // We're only interested in `extern crate`. - match vi.node { - ast::ViewItemExternCrate(..) => (), - _ => return, + match item.node { + ast::ItemExternCrate(_) => {} + _ => { + visit::walk_item(self, item); + return; + } } // Parse the attributes relating to macro / plugin loading. let mut plugin_attr = None; let mut macro_selection = Some(HashSet::new()); // None => load all let mut reexport = HashSet::new(); - for attr in vi.attrs.iter() { + for attr in item.attrs.iter() { let mut used = true; match attr.name().get() { "phase" => { @@ -155,7 +160,10 @@ fn visit_view_item(&mut self, vi: &ast::ViewItem) { } } - self.load_plugin(CrateOrString::Krate(vi), plugin_attr, macro_selection, Some(reexport)) + self.load_plugin(CrateOrString::Krate(item), + plugin_attr, + macro_selection, + Some(reexport)) } fn visit_mac(&mut self, _: &ast::Mac) { diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index d9bb1d769bf..a2bba313cca 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -249,7 +249,7 @@ pub enum EntryFnType { EntryNone, } -#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash)] +#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Show)] pub enum CrateType { CrateTypeExecutable, CrateTypeDylib, @@ -786,7 +786,6 @@ pub fn rustc_optgroups() -> Vec { opt::multi("", "extern", "Specify where an external rust library is \ located", "NAME=PATH"), - opt::opt("", "opt-level", "Optimize with possible levels 0-3", "LEVEL"), opt::opt("", "sysroot", "Override the system root", "PATH"), opt::multi("Z", "", "Set internal debugging options", "FLAG"), opt::opt("", "color", "Configure coloring of output: @@ -794,22 +793,7 @@ pub fn rustc_optgroups() -> Vec { always = always colorize output; never = never colorize output", "auto|always|never"), - // DEPRECATED - opt::flag("", "print-crate-name", "Output the crate name and exit"), - opt::flag("", "print-file-name", "Output the file(s) that would be \ - written if compilation \ - continued and exit"), - opt::opt("", "debuginfo", "Emit DWARF debug info to the objects created: - 0 = no debug info, - 1 = line-tables only (for stacktraces and breakpoints), - 2 = full debug info with variable and type information \ - (same as -g)", "LEVEL"), - opt::flag("", "no-trans", "Run all passes except translation; no output"), - opt::flag("", "no-analysis", "Parse and expand the source, but run no \ - analysis and produce no output"), - opt::flag("", "parse-only", "Parse only; do not compile, assemble, \ - or link"), - opt::flagopt("", "pretty", + opt::flagopt_u("", "pretty", "Pretty-print the input instead of compiling; valid types are: `normal` (un-annotated source), `expanded` (crates expanded), @@ -823,9 +807,6 @@ pub fn rustc_optgroups() -> Vec { `everybody_loops` (all function bodies replaced with `loop {}`).", "TYPE"), opt::opt_u("", "show-span", "Show spans for compiler debugging", "expr|pat|ty"), - opt::flagopt("", "dep-info", - "Output dependency info to after compiling, \ - in a format suitable for use by Makefiles", "FILENAME"), ]); opts } @@ -861,27 +842,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let debugging_opts = build_debugging_options(matches); - let parse_only = if matches.opt_present("parse-only") { - // FIXME(acrichto) remove this eventually - early_warn("--parse-only is deprecated in favor of -Z parse-only"); - true - } else { - debugging_opts.parse_only - }; - let no_trans = if matches.opt_present("no-trans") { - // FIXME(acrichto) remove this eventually - early_warn("--no-trans is deprecated in favor of -Z no-trans"); - true - } else { - debugging_opts.no_trans - }; - let no_analysis = if matches.opt_present("no-analysis") { - // FIXME(acrichto) remove this eventually - early_warn("--no-analysis is deprecated in favor of -Z no-analysis"); - true - } else { - debugging_opts.no_analysis - }; + let parse_only = debugging_opts.parse_only; + let no_trans = debugging_opts.no_trans; + let no_analysis = debugging_opts.no_analysis; if debugging_opts.debug_llvm { unsafe { llvm::LLVMSetDebug(1); } @@ -921,28 +884,10 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { host_triple().to_string()); let opt_level = { if matches.opt_present("O") { - if matches.opt_present("opt-level") { - early_error("-O and --opt-level both provided"); - } if cg.opt_level.is_some() { early_error("-O and -C opt-level both provided"); } Default - } else if matches.opt_present("opt-level") { - // FIXME(acrichto) remove this eventually - early_warn("--opt-level=N is deprecated in favor of -C opt-level=N"); - match matches.opt_str("opt-level").as_ref().map(|s| s.as_slice()) { - None | - Some("0") => No, - Some("1") => Less, - Some("2") => Default, - Some("3") => Aggressive, - Some(arg) => { - early_error(&format!("optimization level needs to be \ - between 0-3 (instead was `{}`)", - arg)[]); - } - } } else { match cg.opt_level { None => No, @@ -960,27 +905,10 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { }; let gc = debugging_opts.gc; let debuginfo = if matches.opt_present("g") { - if matches.opt_present("debuginfo") { - early_error("-g and --debuginfo both provided"); - } if cg.debuginfo.is_some() { early_error("-g and -C debuginfo both provided"); } FullDebugInfo - } else if matches.opt_present("debuginfo") { - // FIXME(acrichto) remove this eventually - early_warn("--debuginfo=N is deprecated in favor of -C debuginfo=N"); - match matches.opt_str("debuginfo").as_ref().map(|s| s.as_slice()) { - Some("0") => NoDebugInfo, - Some("1") => LimitedDebugInfo, - None | - Some("2") => FullDebugInfo, - Some(arg) => { - early_error(&format!("debug info level needs to be between \ - 0-2 (instead was `{}`)", - arg)[]); - } - } } else { match cg.debuginfo { None | Some(0) => NoDebugInfo, @@ -1036,15 +964,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let cfg = parse_cfgspecs(matches.opt_strs("cfg")); let test = matches.opt_present("test"); - let write_dependency_info = if matches.opt_present("dep-info") { - // FIXME(acrichto) remove this eventually - early_warn("--dep-info has been deprecated in favor of --emit"); - (true, matches.opt_str("dep-info").map(|p| Path::new(p))) - } else { - (output_types.contains(&OutputTypeDepInfo), None) - }; + let write_dependency_info = (output_types.contains(&OutputTypeDepInfo), None); - let mut prints = matches.opt_strs("print").into_iter().map(|s| { + let prints = matches.opt_strs("print").into_iter().map(|s| { match s.as_slice() { "crate-name" => PrintRequest::CrateName, "file-names" => PrintRequest::FileNames, @@ -1054,18 +976,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } } }).collect::>(); - if matches.opt_present("print-crate-name") { - // FIXME(acrichto) remove this eventually - early_warn("--print-crate-name has been deprecated in favor of \ - --print crate-name"); - prints.push(PrintRequest::CrateName); - } - if matches.opt_present("print-file-name") { - // FIXME(acrichto) remove this eventually - early_warn("--print-file-name has been deprecated in favor of \ - --print file-names"); - prints.push(PrintRequest::FileNames); - } if !cg.remark.is_empty() && debuginfo == NoDebugInfo { early_warn("-C remark will not show source locations without \ @@ -1159,7 +1069,7 @@ pub fn parse_crate_types_from_list(list_list: Vec) -> Result fmt::Result { match *self { CrateTypeExecutable => "bin".fmt(f), diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 5424b1c8cae..4150335abc3 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -69,65 +69,23 @@ impl Session { pub fn span_fatal(&self, sp: Span, msg: &str) -> ! { self.diagnostic().span_fatal(sp, msg) } + pub fn span_fatal_with_code(&self, sp: Span, msg: &str, code: &str) -> ! { + self.diagnostic().span_fatal_with_code(sp, msg, code) + } pub fn fatal(&self, msg: &str) -> ! { self.diagnostic().handler().fatal(msg) } pub fn span_err(&self, sp: Span, msg: &str) { - // Conditions for enabling multi-line errors: - if !msg.contains("mismatched types") && - !msg.contains("type mismatch resolving") && - !msg.contains("if and else have incompatible types") && - !msg.contains("if may be missing an else clause") && - !msg.contains("match arms have incompatible types") && - !msg.contains("structure constructor specifies a structure of type") { - return self.diagnostic().span_err(sp, msg); + match split_msg_into_multilines(msg) { + Some(msg) => self.diagnostic().span_err(sp, &msg[]), + None => self.diagnostic().span_err(sp, msg) } - - let first = Regex::new(r"[( ]expected").unwrap(); - let second = Regex::new(r" found").unwrap(); - let third = Regex::new( - r"\((values differ|lifetime|cyclic type of infinite size)").unwrap(); - - let mut new_msg = String::new(); - let mut head = 0u; - - // Insert `\n` before expected and found. - for (pos1, pos2) in first.find_iter(msg).zip( - second.find_iter(msg)) { - new_msg = new_msg + - // A `(` may be preceded by a space and it should be trimmed - msg[head..pos1.0].trim_right() + // prefix - "\n" + // insert before first - &msg[pos1.0..pos1.1] + // insert what first matched - &msg[pos1.1..pos2.0] + // between matches - "\n " + // insert before second - // 123 - // `expected` is 3 char longer than `found`. To align the types, `found` gets - // 3 spaces prepended. - &msg[pos2.0..pos2.1]; // insert what second matched - - head = pos2.1; - } - - let mut tail = &msg[head..]; - // Insert `\n` before any remaining messages which match. - for pos in third.find_iter(tail).take(1) { - // The end of the message may just be wrapped in `()` without `expected`/`found`. - // Push this also to a new line and add the final tail after. - new_msg = new_msg + - // `(` is usually preceded by a space and should be trimmed. - tail[..pos.0].trim_right() + // prefix - "\n" + // insert before paren - &tail[pos.0..]; // append the tail - - tail = ""; - } - - new_msg.push_str(tail); - self.diagnostic().span_err(sp, &new_msg[]) } pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) { - self.diagnostic().span_err_with_code(sp, msg, code) + match split_msg_into_multilines(msg) { + Some(msg) => self.diagnostic().span_err_with_code(sp, &msg[], code), + None => self.diagnostic().span_err_with_code(sp, msg, code) + } } pub fn err(&self, msg: &str) { self.diagnostic().handler().err(msg) @@ -285,6 +243,62 @@ pub fn host_filesearch(&self, kind: PathKind) -> filesearch::FileSearch { } } +fn split_msg_into_multilines(msg: &str) -> Option { + // Conditions for enabling multi-line errors: + if !msg.contains("mismatched types") && + !msg.contains("type mismatch resolving") && + !msg.contains("if and else have incompatible types") && + !msg.contains("if may be missing an else clause") && + !msg.contains("match arms have incompatible types") && + !msg.contains("structure constructor specifies a structure of type") { + return None + } + + let first = Regex::new(r"[( ]expected").unwrap(); + let second = Regex::new(r" found").unwrap(); + let third = Regex::new( + r"\((values differ|lifetime|cyclic type of infinite size)").unwrap(); + + let mut new_msg = String::new(); + let mut head = 0u; + + // Insert `\n` before expected and found. + for (pos1, pos2) in first.find_iter(msg).zip( + second.find_iter(msg)) { + new_msg = new_msg + + // A `(` may be preceded by a space and it should be trimmed + msg[head..pos1.0].trim_right() + // prefix + "\n" + // insert before first + &msg[pos1.0..pos1.1] + // insert what first matched + &msg[pos1.1..pos2.0] + // between matches + "\n " + // insert before second + // 123 + // `expected` is 3 char longer than `found`. To align the types, `found` gets + // 3 spaces prepended. + &msg[pos2.0..pos2.1]; // insert what second matched + + head = pos2.1; + } + + let mut tail = &msg[head..]; + // Insert `\n` before any remaining messages which match. + for pos in third.find_iter(tail).take(1) { + // The end of the message may just be wrapped in `()` without `expected`/`found`. + // Push this also to a new line and add the final tail after. + new_msg = new_msg + + // `(` is usually preceded by a space and should be trimmed. + tail[..pos.0].trim_right() + // prefix + "\n" + // insert before paren + &tail[pos.0..]; // append the tail + + tail = ""; + } + + new_msg.push_str(tail); + + return Some(new_msg) +} + pub fn build_session(sopts: config::Options, local_crate_source_file: Option, registry: diagnostics::registry::Registry) diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs index 0cf04fe0a00..dfc27d3ae68 100644 --- a/src/librustc/session/search_paths.rs +++ b/src/librustc/session/search_paths.rs @@ -36,13 +36,13 @@ pub fn new() -> SearchPaths { pub fn add_path(&mut self, path: &str) { let (kind, path) = if path.starts_with("native=") { - (PathKind::Native, path.slice_from("native=".len())) + (PathKind::Native, &path["native=".len()..]) } else if path.starts_with("crate=") { - (PathKind::Crate, path.slice_from("crate=".len())) + (PathKind::Crate, &path["crate=".len()..]) } else if path.starts_with("dependency=") { - (PathKind::Dependency, path.slice_from("dependency=".len())) + (PathKind::Dependency, &path["dependency=".len()..]) } else if path.starts_with("all=") { - (PathKind::All, path.slice_from("all=".len())) + (PathKind::All, &path["all=".len()..]) } else { (PathKind::All, path) }; diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index c505e9e3112..8915d55e206 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -12,7 +12,7 @@ use std::cell::{RefCell, Cell}; use std::collections::HashMap; -use std::fmt::Show; +use std::fmt::Debug; use std::hash::{Hash, Hasher}; use std::iter::repeat; use std::time::Duration; @@ -58,7 +58,7 @@ pub fn time(do_it: bool, what: &str, u: U, f: F) -> T where } pub fn indent(op: F) -> R where - R: Show, + R: Debug, F: FnOnce() -> R, { // Use in conjunction with the log post-processor like `src/etc/indenter` diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index fb44d0cadfa..c5aced4eb86 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -164,7 +164,7 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region) fn explain_span(cx: &ctxt, heading: &str, span: Span) -> (String, Option) { let lo = cx.sess.codemap().lookup_char_pos_adj(span.lo); - (format!("the {} at {}:{}", heading, lo.line, lo.col.to_uint()), + (format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize()), Some(span)) } } @@ -237,15 +237,6 @@ pub fn mt_to_string<'tcx>(cx: &ctxt<'tcx>, m: &mt<'tcx>) -> String { ty_to_string(cx, m.ty)) } -pub fn trait_store_to_string(cx: &ctxt, s: ty::TraitStore) -> String { - match s { - ty::UniqTraitStore => "Box ".to_string(), - ty::RegionTraitStore(r, m) => { - format!("{}{}", region_ptr_to_string(cx, r), mutability_to_string(m)) - } - } -} - pub fn vec_map_to_string(ts: &[T], f: F) -> String where F: FnMut(&T) -> String, { @@ -285,7 +276,7 @@ fn bare_fn_to_string<'tcx>(cx: &ctxt<'tcx>, _ => { } } - push_sig_to_string(cx, &mut s, '(', ')', sig, ""); + push_sig_to_string(cx, &mut s, '(', ')', sig); match opt_def_id { Some(def_id) => { @@ -303,13 +294,6 @@ fn bare_fn_to_string<'tcx>(cx: &ctxt<'tcx>, fn closure_to_string<'tcx>(cx: &ctxt<'tcx>, cty: &ty::ClosureTy<'tcx>) -> String { let mut s = String::new(); - match cty.store { - ty::UniqTraitStore => {} - ty::RegionTraitStore(region, _) => { - s.push_str(®ion_to_string(cx, "", true, region)[]); - } - } - match cty.unsafety { ast::Unsafety::Normal => {} ast::Unsafety::Unsafe => { @@ -318,24 +302,7 @@ fn closure_to_string<'tcx>(cx: &ctxt<'tcx>, cty: &ty::ClosureTy<'tcx>) -> String } }; - let bounds_str = cty.bounds.user_string(cx); - - match cty.store { - ty::UniqTraitStore => { - assert_eq!(cty.onceness, ast::Once); - s.push_str("proc"); - push_sig_to_string(cx, &mut s, '(', ')', &cty.sig, - &bounds_str[]); - } - ty::RegionTraitStore(..) => { - match cty.onceness { - ast::Many => {} - ast::Once => s.push_str("once ") - } - push_sig_to_string(cx, &mut s, '|', '|', &cty.sig, - &bounds_str[]); - } - } + push_sig_to_string(cx, &mut s, '|', '|', &cty.sig); s } @@ -344,8 +311,7 @@ fn push_sig_to_string<'tcx>(cx: &ctxt<'tcx>, s: &mut String, bra: char, ket: char, - sig: &ty::PolyFnSig<'tcx>, - bounds: &str) { + sig: &ty::PolyFnSig<'tcx>) { s.push(bra); let strs = sig.0.inputs .iter() @@ -357,11 +323,6 @@ fn push_sig_to_string<'tcx>(cx: &ctxt<'tcx>, } s.push(ket); - if !bounds.is_empty() { - s.push_str(":"); - s.push_str(bounds); - } - match sig.0.output { ty::FnConverging(t) => { if !ty::type_is_nil(t) { @@ -542,7 +503,7 @@ pub fn parameterized<'tcx>(cx: &ctxt<'tcx>, 0 }; - for t in tps[..(tps.len() - num_defaults)].iter() { + for t in tps[..tps.len() - num_defaults].iter() { strs.push(ty_to_string(cx, *t)) } @@ -550,9 +511,9 @@ pub fn parameterized<'tcx>(cx: &ctxt<'tcx>, format!("{}({}){}", base, if strs[0].starts_with("(") && strs[0].ends_with(",)") { - &strs[0][1 .. (strs[0].len() - 2)] // Remove '(' and ',)' + &strs[0][1 .. strs[0].len() - 2] // Remove '(' and ',)' } else if strs[0].starts_with("(") && strs[0].ends_with(")") { - &strs[0][1 .. (strs[0].len() - 1)] // Remove '(' and ')' + &strs[0][1 .. strs[0].len() - 1] // Remove '(' and ')' } else { &strs[0][] }, @@ -1090,12 +1051,6 @@ fn repr(&self, tcx: &ctxt<'tcx>) -> String { } } -impl<'tcx> Repr<'tcx> for ty::TraitStore { - fn repr(&self, tcx: &ctxt) -> String { - trait_store_to_string(tcx, *self) - } -} - impl<'tcx> Repr<'tcx> for ty::BuiltinBound { fn repr(&self, _tcx: &ctxt) -> String { format!("{:?}", *self) diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs index 7ea192b8d6b..fa754b4a301 100644 --- a/src/librustc_back/archive.rs +++ b/src/librustc_back/archive.rs @@ -59,7 +59,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option, let mut cmd = Command::new(ar); cmd.arg(args).args(paths); - debug!("{}", cmd); + debug!("{:?}", cmd); match cwd { Some(p) => { @@ -73,9 +73,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option, Ok(prog) => { let o = prog.wait_with_output().unwrap(); if !o.status.success() { - handler.err(&format!("{} failed with: {}", - cmd, - o.status)[]); + handler.err(&format!("{:?} failed with: {}", cmd, o.status)[]); handler.note(&format!("stdout ---\n{}", str::from_utf8(&o.output[]).unwrap())[]); handler.note(&format!("stderr ---\n{}", diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs index e376ac50dcd..0228098b8f8 100644 --- a/src/librustc_back/sha2.rs +++ b/src/librustc_back/sha2.rs @@ -156,7 +156,7 @@ fn input(&mut self, input: &[u8], mut func: F) where // While we have at least a full buffer size chunk's worth of data, process that data // without copying it into the buffer while input.len() - i >= size { - func(&input[i..(i + size)]); + func(&input[i..i + size]); i += size; } diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs index b71e465b938..ebeaf3e6e22 100644 --- a/src/librustc_back/svh.rs +++ b/src/librustc_back/svh.rs @@ -52,7 +52,7 @@ use syntax::ast; use syntax::visit; -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Show)] pub struct Svh { hash: String, } @@ -117,13 +117,7 @@ fn hex(b: u64) -> char { } } -impl fmt::Show for Svh { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Svh {{ {} }}", self.as_str()) - } -} - -impl fmt::String for Svh { +impl fmt::Display for Svh { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.pad(self.as_str()) } @@ -188,7 +182,6 @@ enum SawAbiComponent<'a> { SawLifetimeDef(token::InternedString), SawMod, - SawViewItem, SawForeignItem, SawItem, SawDecl, @@ -436,19 +429,6 @@ fn visit_stmt(&mut self, s: &Stmt) { SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s) } - fn visit_view_item(&mut self, i: &ViewItem) { - // Two kinds of view items can affect the ABI for a crate: - // exported `pub use` view items (since that may expose - // items that downstream crates can call), and `use - // foo::Trait`, since changing that may affect method - // resolution. - // - // The simplest approach to handling both of the above is - // just to adopt the same simple-minded (fine-grained) - // hash that I am deploying elsewhere here. - SawViewItem.hash(self.st); visit::walk_view_item(self, i) - } - fn visit_foreign_item(&mut self, i: &ForeignItem) { // FIXME (#14132) ideally we would incorporate privacy (or // perhaps reachability) somewhere here, so foreign items diff --git a/src/librustc_back/target/aarch64_linux_android.rs b/src/librustc_back/target/aarch64_linux_android.rs new file mode 100644 index 00000000000..313c0dc2a6e --- /dev/null +++ b/src/librustc_back/target/aarch64_linux_android.rs @@ -0,0 +1,28 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use target::Target; + +pub fn target() -> Target { + let mut base = super::linux_base::opts(); + base.pre_link_args.push("-Wl,--allow-multiple-definition".to_string()); + base.position_independent_executables = true; + Target { + data_layout: "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\ + f32:32:32-f64:64:64-v64:64:64-v128:128:128-a:0:64-\ + n32:64-S128".to_string(), + llvm_target: "aarch64-linux-android".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + arch: "aarch64".to_string(), + target_os: "android".to_string(), + options: base, + } +} diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index f8eabb4375f..4626f2dc483 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -65,6 +65,7 @@ mod arm_unknown_linux_gnueabi; mod arm_unknown_linux_gnueabihf; mod aarch64_apple_ios; +mod aarch64_linux_android; mod aarch64_unknown_linux_gnu; mod i686_apple_darwin; mod i686_pc_windows_gnu; @@ -357,6 +358,7 @@ macro_rules! load_specific { i386_apple_ios, x86_64_apple_ios, aarch64_apple_ios, + aarch64_linux_android, armv7_apple_ios, armv7s_apple_ios, diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index d5ad201eabf..0ade916f639 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -370,7 +370,7 @@ pub fn check_for_conflicting_loans(&self, scope: region::CodeExtent) { for (i, &x) in new_loan_indices.iter().enumerate() { let old_loan = &self.all_loans[x]; - for &y in new_loan_indices.slice_from(i+1).iter() { + for &y in new_loan_indices[(i+1) ..].iter() { let new_loan = &self.all_loans[y]; self.report_error_if_loans_conflict(old_loan, new_loan); } diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 889a359b019..b1cc3a65120 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -491,7 +491,7 @@ fn visit_expr(&mut self, ex: &Expr) { if let ast::ExprAddrOf(mutbl, ref base) = ex.node { let param_env = ty::empty_parameter_environment(self.bccx.tcx); let mc = mc::MemCategorizationContext::new(¶m_env); - let base_cmt = mc.cat_expr(&**base).unwrap(); + let base_cmt = mc.cat_expr(&**base).ok().unwrap(); let borrow_kind = ty::BorrowKind::from_mutbl(mutbl); // Check that we don't allow borrows of unsafe static items. if check_aliasability(self.bccx, ex.span, euv::AddrOf, diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 50ff4546c37..0e940b85bd8 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -61,7 +61,6 @@ use rustc::lint; use rustc::metadata; use rustc::metadata::creader::CrateOrString::Str; -use rustc::DIAGNOSTICS; use rustc::util::common::time; use std::cmp::Ordering::Equal; @@ -98,7 +97,7 @@ fn run_compiler(args: &[String]) { None => return }; - let descriptions = diagnostics::registry::Registry::new(&DIAGNOSTICS); + let descriptions = diagnostics_registry(); match matches.opt_str("explain") { Some(ref code) => { match descriptions.find_description(&code[]) { @@ -154,10 +153,14 @@ fn run_compiler(args: &[String]) { return } - let pretty = matches.opt_default("pretty", "normal").map(|a| { - // stable pretty-print variants only - pretty::parse_pretty(&sess, a.as_slice(), false) - }); + let pretty = if sess.opts.debugging_opts.unstable_options { + matches.opt_default("pretty", "normal").map(|a| { + // stable pretty-print variants only + pretty::parse_pretty(&sess, a.as_slice(), false) + }) + } else { + None + }; let pretty = if pretty.is_none() && sess.unstable_options() { matches.opt_str("xpretty").map(|a| { @@ -659,8 +662,20 @@ pub fn monitor(f: F) { } } +pub fn diagnostics_registry() -> diagnostics::registry::Registry { + use syntax::diagnostics::registry::Registry; + + let all_errors = Vec::new() + + rustc::diagnostics::DIAGNOSTICS.as_slice() + + rustc_typeck::diagnostics::DIAGNOSTICS.as_slice() + + rustc_resolve::diagnostics::DIAGNOSTICS.as_slice(); + + Registry::new(&*all_errors) +} + pub fn main() { let args = std::os::args(); let result = run(args); std::os::set_exit_status(result); } + diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 279442891be..582e1032324 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -477,7 +477,7 @@ fn expr_to_block(rules: ast::BlockCheckMode, e: Option>) -> P { P(ast::Block { expr: e, - view_items: vec![], stmts: vec![], rules: rules, + stmts: vec![], rules: rules, id: ast::DUMMY_NODE_ID, span: codemap::DUMMY_SP, }) } diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index f68c76f4c44..cd28a27f988 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -200,6 +200,7 @@ fn search(this: &Env, } return match it.node { + ast::ItemUse(..) | ast::ItemExternCrate(..) | ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemFn(..) | ast::ItemForeignMod(..) | ast::ItemTy(..) => { None diff --git a/src/librustc_llvm/diagnostic.rs b/src/librustc_llvm/diagnostic.rs index 464f9f98e7f..db2a569cdef 100644 --- a/src/librustc_llvm/diagnostic.rs +++ b/src/librustc_llvm/diagnostic.rs @@ -14,6 +14,7 @@ pub use self::Diagnostic::*; use libc::c_char; +use std::ptr; use {ValueRef, TwineRef, DebugLocRef, DiagnosticInfoRef}; @@ -52,10 +53,10 @@ unsafe fn unpack(kind: OptimizationDiagnosticKind, di: DiagnosticInfoRef) let mut opt = OptimizationDiagnostic { kind: kind, - pass_name: 0 as *const c_char, - function: 0 as ValueRef, - debug_loc: 0 as DebugLocRef, - message: 0 as TwineRef, + pass_name: ptr::null(), + function: ptr::null_mut(), + debug_loc: ptr::null_mut(), + message: ptr::null_mut(), }; super::LLVMUnpackOptimizationDiagnostic(di, diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 4c9a25f42fb..eded88bb62e 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -53,7 +53,7 @@ use std::ffi::CString; use std::cell::RefCell; -use std::{raw, mem}; +use std::{raw, mem, ptr}; use libc::{c_uint, c_ushort, uint64_t, c_int, size_t, c_char}; use libc::{c_longlong, c_ulonglong, c_void}; use debuginfo::{DIBuilderRef, DIDescriptor, @@ -2262,19 +2262,18 @@ pub unsafe fn static_link_hack_this_sucks() { LLVMInitializePowerPCAsmPrinter(); LLVMInitializePowerPCAsmParser(); - LLVMRustSetLLVMOptions(0 as c_int, - 0 as *const _); + LLVMRustSetLLVMOptions(0 as c_int, ptr::null()); - LLVMPassManagerBuilderPopulateModulePassManager(0 as *mut _, 0 as *mut _); - LLVMPassManagerBuilderPopulateLTOPassManager(0 as *mut _, 0 as *mut _, False, False); - LLVMPassManagerBuilderPopulateFunctionPassManager(0 as *mut _, 0 as *mut _); - LLVMPassManagerBuilderSetOptLevel(0 as *mut _, 0 as c_uint); - LLVMPassManagerBuilderUseInlinerWithThreshold(0 as *mut _, 0 as c_uint); - LLVMWriteBitcodeToFile(0 as *mut _, 0 as *const _); + LLVMPassManagerBuilderPopulateModulePassManager(ptr::null_mut(), ptr::null_mut()); + LLVMPassManagerBuilderPopulateLTOPassManager(ptr::null_mut(), ptr::null_mut(), False, False); + LLVMPassManagerBuilderPopulateFunctionPassManager(ptr::null_mut(), ptr::null_mut()); + LLVMPassManagerBuilderSetOptLevel(ptr::null_mut(), 0 as c_uint); + LLVMPassManagerBuilderUseInlinerWithThreshold(ptr::null_mut(), 0 as c_uint); + LLVMWriteBitcodeToFile(ptr::null_mut(), ptr::null()); LLVMPassManagerBuilderCreate(); - LLVMPassManagerBuilderDispose(0 as *mut _); + LLVMPassManagerBuilderDispose(ptr::null_mut()); - LLVMRustLinkInExternalBitcode(0 as *mut _, 0 as *const _, 0 as size_t); + LLVMRustLinkInExternalBitcode(ptr::null_mut(), ptr::null(), 0 as size_t); LLVMLinkInMCJIT(); LLVMLinkInInterpreter(); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index e12c195a3af..414dbb96263 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -830,6 +830,38 @@ fn check_method(&mut self, span: Span, origin: &MethodOrigin, impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &ast::Item) { + match item.node { + ast::ItemUse(ref vpath) => { + match vpath.node { + ast::ViewPathSimple(..) | ast::ViewPathGlob(..) => {} + ast::ViewPathList(ref prefix, ref list) => { + for pid in list.iter() { + match pid.node { + ast::PathListIdent { id, name } => { + debug!("privacy - ident item {}", id); + let seg = ast::PathSegment { + identifier: name, + parameters: ast::PathParameters::none(), + }; + let segs = vec![seg]; + let path = ast::Path { + global: false, + span: pid.span, + segments: segs, + }; + self.check_path(pid.span, id, &path); + } + ast::PathListMod { id } => { + debug!("privacy - mod item {}", id); + self.check_path(pid.span, id, prefix); + } + } + } + } + } + } + _ => {} + } let orig_curitem = replace(&mut self.curitem, item.id); visit::walk_item(self, item); self.curitem = orig_curitem; @@ -926,42 +958,6 @@ struct type?!"), visit::walk_expr(self, expr); } - fn visit_view_item(&mut self, a: &ast::ViewItem) { - match a.node { - ast::ViewItemExternCrate(..) => {} - ast::ViewItemUse(ref vpath) => { - match vpath.node { - ast::ViewPathSimple(..) | ast::ViewPathGlob(..) => {} - ast::ViewPathList(ref prefix, ref list, _) => { - for pid in list.iter() { - match pid.node { - ast::PathListIdent { id, name } => { - debug!("privacy - ident item {}", id); - let seg = ast::PathSegment { - identifier: name, - parameters: ast::PathParameters::none(), - }; - let segs = vec![seg]; - let path = ast::Path { - global: false, - span: pid.span, - segments: segs, - }; - self.check_path(pid.span, id, &path); - } - ast::PathListMod { id } => { - debug!("privacy - mod item {}", id); - self.check_path(pid.span, id, prefix); - } - } - } - } - } - } - } - visit::walk_view_item(self, a); - } - fn visit_pat(&mut self, pattern: &ast::Pat) { // Foreign functions do not have their patterns mapped in the def_map, // and there's nothing really relevant there anyway, so don't bother @@ -1069,23 +1065,6 @@ fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl, visit::walk_fn(self, fk, fd, b, s); self.in_fn = orig_in_fn; } - - fn visit_view_item(&mut self, i: &ast::ViewItem) { - match i.vis { - ast::Inherited => {} - ast::Public => { - if self.in_fn { - self.tcx.sess.span_err(i.span, "unnecessary `pub`, imports \ - in functions are never \ - reachable"); - } else if let ast::ViewItemExternCrate(..) = i.node { - self.tcx.sess.span_err(i.span, "`pub` visibility \ - is not allowed"); - } - } - } - visit::walk_view_item(self, i); - } } impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> { @@ -1162,7 +1141,7 @@ fn check_sane_privacy(&self, item: &ast::Item) { ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemStruct(..) | ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) | - ast::ItemMac(..) => {} + ast::ItemExternCrate(_) | ast::ItemUse(_) | ast::ItemMac(..) => {} } } @@ -1219,6 +1198,7 @@ fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: ast::Visibility) { } } + ast::ItemExternCrate(_) | ast::ItemUse(_) | ast::ItemStatic(..) | ast::ItemConst(..) | ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) | ast::ItemMac(..) => {} @@ -1521,11 +1501,9 @@ fn visit_struct_field(&mut self, s: &ast::StructField) { // we don't need to introspect into these at all: an - // expression/block context can't possibly contain exported - // things, and neither do view_items. (Making them no-ops stops us - // from traversing the whole AST without having to be super - // careful about our `walk_...` calls above.) - fn visit_view_item(&mut self, _: &ast::ViewItem) {} + // expression/block context can't possibly contain exported things. + // (Making them no-ops stops us from traversing the whole AST without + // having to be super careful about our `walk_...` calls above.) fn visit_block(&mut self, _: &ast::Block) {} fn visit_expr(&mut self, _: &ast::Expr) {} } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 21eec383df4..65bd83d7937 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -39,9 +39,9 @@ use syntax::ast::{Block, Crate}; use syntax::ast::{DeclItem, DefId}; use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic}; -use syntax::ast::{Item, ItemConst, ItemEnum, ItemFn}; +use syntax::ast::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn}; use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic}; -use syntax::ast::{ItemStruct, ItemTrait, ItemTy}; +use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse}; use syntax::ast::{MethodImplItem, Name, NamedField, NodeId}; use syntax::ast::{PathListIdent, PathListMod}; use syntax::ast::{Public, SelfStatic}; @@ -50,8 +50,7 @@ use syntax::ast::TupleVariantKind; use syntax::ast::TyObjectSum; use syntax::ast::{TypeImplItem, UnnamedField}; -use syntax::ast::{Variant, ViewItem, ViewItemExternCrate}; -use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple}; +use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple}; use syntax::ast::{Visibility}; use syntax::ast::TyPath; use syntax::ast; @@ -238,11 +237,6 @@ fn add_child(&self, } fn block_needs_anonymous_module(&mut self, block: &Block) -> bool { - // If the block has view items, we need an anonymous module. - if block.view_items.len() > 0 { - return true; - } - // Check each statement. for statement in block.stmts.iter() { match statement.node { @@ -262,7 +256,7 @@ fn block_needs_anonymous_module(&mut self, block: &Block) -> bool { } } - // If we found neither view items nor items, we don't need to create + // If we found no items, we don't need to create // an anonymous module. return false; @@ -280,6 +274,133 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc) -> let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE; match item.node { + ItemUse(ref view_path) => { + // Extract and intern the module part of the path. For + // globs and lists, the path is found directly in the AST; + // for simple paths we have to munge the path a little. + let module_path = match view_path.node { + ViewPathSimple(_, ref full_path) => { + full_path.segments + .init() + .iter().map(|ident| ident.identifier.name) + .collect() + } + + ViewPathGlob(ref module_ident_path) | + ViewPathList(ref module_ident_path, _) => { + module_ident_path.segments + .iter().map(|ident| ident.identifier.name).collect() + } + }; + + // Build up the import directives. + let shadowable = item.attrs.iter().any(|attr| { + attr.name() == token::get_name(special_idents::prelude_import.name) + }); + let shadowable = if shadowable { + Shadowable::Always + } else { + Shadowable::Never + }; + + match view_path.node { + ViewPathSimple(binding, ref full_path) => { + let source_name = + full_path.segments.last().unwrap().identifier.name; + if token::get_name(source_name).get() == "mod" || + token::get_name(source_name).get() == "self" { + self.resolve_error(view_path.span, + "`self` imports are only allowed within a { } list"); + } + + let subclass = SingleImport(binding.name, + source_name); + self.build_import_directive(&**parent, + module_path, + subclass, + view_path.span, + item.id, + is_public, + shadowable); + } + ViewPathList(_, ref source_items) => { + // Make sure there's at most one `mod` import in the list. + let mod_spans = source_items.iter().filter_map(|item| match item.node { + PathListMod { .. } => Some(item.span), + _ => None + }).collect::>(); + if mod_spans.len() > 1 { + self.resolve_error(mod_spans[0], + "`self` import can only appear once in the list"); + for other_span in mod_spans.iter().skip(1) { + self.session.span_note(*other_span, + "another `self` import appears here"); + } + } + + for source_item in source_items.iter() { + let (module_path, name) = match source_item.node { + PathListIdent { name, .. } => + (module_path.clone(), name.name), + PathListMod { .. } => { + let name = match module_path.last() { + Some(name) => *name, + None => { + self.resolve_error(source_item.span, + "`self` import can only appear in an import list \ + with a non-empty prefix"); + continue; + } + }; + let module_path = module_path.init(); + (module_path.to_vec(), name) + } + }; + self.build_import_directive( + &**parent, + module_path, + SingleImport(name, name), + source_item.span, + source_item.node.id(), + is_public, + shadowable); + } + } + ViewPathGlob(_) => { + self.build_import_directive(&**parent, + module_path, + GlobImport, + view_path.span, + item.id, + is_public, + shadowable); + } + } + parent.clone() + } + + ItemExternCrate(_) => { + // n.b. we don't need to look at the path option here, because cstore already did + for &crate_id in self.session.cstore + .find_extern_mod_stmt_cnum(item.id).iter() { + let def_id = DefId { krate: crate_id, node: 0 }; + self.external_exports.insert(def_id); + let parent_link = ModuleParentLink(parent.downgrade(), name); + let external_module = Rc::new(Module::new(parent_link, + Some(def_id), + NormalModuleKind, + false, + true)); + debug!("(build reduced graph for item) found extern `{}`", + self.module_to_string(&*external_module)); + self.check_for_conflicts_between_external_crates(&**parent, name, sp); + parent.external_module_children.borrow_mut() + .insert(name, external_module.clone()); + self.build_reduced_graph_for_external_crate(&external_module); + } + parent.clone() + } + ItemMod(..) => { let name_bindings = self.add_child(name, parent, ForbidDuplicateModules, sp); @@ -650,145 +771,6 @@ fn build_reduced_graph_for_variant(&mut self, variant.span, PUBLIC | IMPORTABLE); } - /// Constructs the reduced graph for one 'view item'. View items consist - /// of imports and use directives. - fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem, parent: &Rc) { - match view_item.node { - ViewItemUse(ref view_path) => { - // Extract and intern the module part of the path. For - // globs and lists, the path is found directly in the AST; - // for simple paths we have to munge the path a little. - let module_path = match view_path.node { - ViewPathSimple(_, ref full_path, _) => { - full_path.segments - .init() - .iter().map(|ident| ident.identifier.name) - .collect() - } - - ViewPathGlob(ref module_ident_path, _) | - ViewPathList(ref module_ident_path, _, _) => { - module_ident_path.segments - .iter().map(|ident| ident.identifier.name).collect() - } - }; - - // Build up the import directives. - let is_public = view_item.vis == ast::Public; - let shadowable = - view_item.attrs - .iter() - .any(|attr| { - attr.name() == token::get_name( - special_idents::prelude_import.name) - }); - let shadowable = if shadowable { - Shadowable::Always - } else { - Shadowable::Never - }; - - match view_path.node { - ViewPathSimple(binding, ref full_path, id) => { - let source_name = - full_path.segments.last().unwrap().identifier.name; - if token::get_name(source_name).get() == "mod" || - token::get_name(source_name).get() == "self" { - self.resolve_error(view_path.span, - "`self` imports are only allowed within a { } list"); - } - - let subclass = SingleImport(binding.name, - source_name); - self.build_import_directive(&**parent, - module_path, - subclass, - view_path.span, - id, - is_public, - shadowable); - } - ViewPathList(_, ref source_items, _) => { - // Make sure there's at most one `mod` import in the list. - let mod_spans = source_items.iter().filter_map(|item| match item.node { - PathListMod { .. } => Some(item.span), - _ => None - }).collect::>(); - if mod_spans.len() > 1 { - self.resolve_error(mod_spans[0], - "`self` import can only appear once in the list"); - for other_span in mod_spans.iter().skip(1) { - self.session.span_note(*other_span, - "another `self` import appears here"); - } - } - - for source_item in source_items.iter() { - let (module_path, name) = match source_item.node { - PathListIdent { name, .. } => - (module_path.clone(), name.name), - PathListMod { .. } => { - let name = match module_path.last() { - Some(name) => *name, - None => { - self.resolve_error(source_item.span, - "`self` import can only appear in an import list \ - with a non-empty prefix"); - continue; - } - }; - let module_path = module_path.init(); - (module_path.to_vec(), name) - } - }; - self.build_import_directive( - &**parent, - module_path, - SingleImport(name, name), - source_item.span, - source_item.node.id(), - is_public, - shadowable); - } - } - ViewPathGlob(_, id) => { - self.build_import_directive(&**parent, - module_path, - GlobImport, - view_path.span, - id, - is_public, - shadowable); - } - } - } - - ViewItemExternCrate(name, _, node_id) => { - // n.b. we don't need to look at the path option here, because cstore already did - for &crate_id in self.session.cstore - .find_extern_mod_stmt_cnum(node_id).iter() { - let def_id = DefId { krate: crate_id, node: 0 }; - self.external_exports.insert(def_id); - let parent_link = ModuleParentLink(parent.downgrade(), name.name); - let external_module = Rc::new(Module::new(parent_link, - Some(def_id), - NormalModuleKind, - false, - true)); - debug!("(build reduced graph for item) found extern `{}`", - self.module_to_string(&*external_module)); - self.check_for_conflicts_between_external_crates( - &**parent, - name.name, - view_item.span); - parent.external_module_children.borrow_mut() - .insert(name.name, external_module.clone()); - self.build_reduced_graph_for_external_crate(&external_module); - } - } - } - } - /// Constructs the reduced graph for one foreign item. fn build_reduced_graph_for_foreign_item(&mut self, foreign_item: &ForeignItem, @@ -1270,10 +1252,6 @@ fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) { }) } - fn visit_view_item(&mut self, view_item: &ViewItem) { - self.builder.build_reduced_graph_for_view_item(view_item, &self.parent); - } - fn visit_block(&mut self, block: &Block) { let np = self.builder.build_reduced_graph_for_block(block, &self.parent); let old_parent = replace(&mut self.parent, np); diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 18066a7b94b..97370112ab4 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -25,7 +25,6 @@ use rustc::lint; use rustc::middle::privacy::{DependsOn, LastImport, Used, Unused}; use syntax::ast; -use syntax::ast::{ViewItem, ViewItemExternCrate, ViewItemUse}; use syntax::ast::{ViewPathGlob, ViewPathList, ViewPathSimple}; use syntax::codemap::{Span, DUMMY_SP}; use syntax::visit::{self, Visitor}; @@ -109,53 +108,54 @@ fn finalize_import(&mut self, id: ast::NodeId, span: Span) { } impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { - fn visit_view_item(&mut self, vi: &ViewItem) { + fn visit_item(&mut self, item: &ast::Item) { // Ignore is_public import statements because there's no way to be sure // whether they're used or not. Also ignore imports with a dummy span // because this means that they were generated in some fashion by the // compiler and we don't need to consider them. - if vi.vis == ast::Public || vi.span == DUMMY_SP { - visit::walk_view_item(self, vi); + if item.vis == ast::Public || item.span == DUMMY_SP { + visit::walk_item(self, item); return; } - match vi.node { - ViewItemExternCrate(_, _, id) => { - if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(id) { + match item.node { + ast::ItemExternCrate(_) => { + if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(item.id) { if !self.used_crates.contains(&crate_num) { self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES, - id, - vi.span, + item.id, + item.span, "unused extern crate".to_string()); } } }, - ViewItemUse(ref p) => { + ast::ItemUse(ref p) => { match p.node { - ViewPathSimple(_, _, id) => { - self.finalize_import(id, p.span) + ViewPathSimple(_, _) => { + self.finalize_import(item.id, p.span) } - ViewPathList(_, ref list, _) => { + ViewPathList(_, ref list) => { for i in list.iter() { self.finalize_import(i.node.id(), i.span); } } - ViewPathGlob(_, id) => { - if !self.used_imports.contains(&(id, TypeNS)) && - !self.used_imports.contains(&(id, ValueNS)) { + ViewPathGlob(_) => { + if !self.used_imports.contains(&(item.id, TypeNS)) && + !self.used_imports.contains(&(item.id, ValueNS)) { self.session .add_lint(lint::builtin::UNUSED_IMPORTS, - id, + item.id, p.span, "unused import".to_string()); } } } } + _ => {} } - visit::walk_view_item(self, vi); + visit::walk_item(self, item); } } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs new file mode 100644 index 00000000000..dd9ccfbda7c --- /dev/null +++ b/src/librustc_resolve/diagnostics.rs @@ -0,0 +1,29 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(non_snake_case)] + +register_diagnostics! { + E0154, + E0157, + E0153, + E0251, // a named type or value has already been imported in this module + E0252, // a named type or value has already been imported in this module + E0253, // not directly importable + E0254, // import conflicts with imported crate in this module + E0255, // import conflicts with value in this module + E0256, // import conflicts with type in this module + E0257, // inherent implementations are only allowen on types defined in the current module + E0258, // import conflicts with existing submodule + E0259, // an extern crate has already been imported into this module + E0260 // name conflicts with an external crate that has been imported into this module +} + +__build_diagnostic_array! { DIAGNOSTICS } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 31999faa6df..94801545c2f 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -65,10 +65,10 @@ use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall}; use syntax::ast::{ExprPath, ExprQPath, ExprStruct, FnDecl}; use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics}; -use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemFn}; -use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic}; -use syntax::ast::{ItemStruct, ItemTrait, ItemTy, Local, LOCAL_CRATE}; -use syntax::ast::{MethodImplItem, Mod, Name, NodeId}; +use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate}; +use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic}; +use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse}; +use syntax::ast::{Local, MethodImplItem, Mod, Name, NodeId}; use syntax::ast::{Pat, PatEnum, PatIdent, PatLit}; use syntax::ast::{PatRange, PatStruct, Path}; use syntax::ast::{PolyTraitRef, PrimTy, SelfExplicit}; @@ -97,6 +97,10 @@ use std::rc::{Rc, Weak}; use std::uint; +// NB: This module needs to be declared first so diagnostics are +// registered before they are used. +pub mod diagnostics; + mod check_unused; mod record_exports; mod build_reduced_graph; @@ -536,7 +540,7 @@ fn all_imports_resolved(&self) -> bool { } } -impl fmt::Show for Module { +impl fmt::Debug for Module { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}, kind: {:?}, {}", self.def_id, @@ -1139,7 +1143,7 @@ fn record_import_use(&mut self, import_id: NodeId, name: Name) { } fn get_trait_name(&self, did: DefId) -> Name { - if did.krate == LOCAL_CRATE { + if did.krate == ast::LOCAL_CRATE { self.ast_map.expect_item(did.node).ident.name } else { csearch::get_trait_name(&self.session.cstore, did) @@ -1718,7 +1722,7 @@ fn merge_import_resolution(&mut self, in this module", namespace_name, token::get_name(name).get()); - self.session.span_err(import_directive.span, msg.as_slice()); + span_err!(self.session, import_directive.span, E0251, "{}", msg.as_slice()); } else { let target = Target::new(containing_module.clone(), name_bindings.clone(), @@ -1748,10 +1752,6 @@ fn check_for_conflicting_import(&mut self, import_span: Span, name: Name, namespace: Namespace) { - if self.session.features.borrow().import_shadowing { - return - } - debug!("check_for_conflicting_import: {}; target exists: {}", token::get_name(name).get(), target.is_some()); @@ -1765,7 +1765,7 @@ fn check_for_conflicting_import(&mut self, ValueNS => "value", }, token::get_name(name).get()); - self.session.span_err(import_span, &msg[]); + span_err!(self.session, import_span, E0252, "{}", &msg[]); } Some(_) | None => {} } @@ -1780,7 +1780,7 @@ fn check_that_import_is_importable(&mut self, if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) { let msg = format!("`{}` is not directly importable", token::get_name(name)); - self.session.span_err(import_span, &msg[]); + span_err!(self.session, import_span, E0253, "{}", &msg[]); } } @@ -1791,10 +1791,6 @@ fn check_for_conflicts_between_imports_and_items(&mut self, &ImportResolution, import_span: Span, name: Name) { - if self.session.features.borrow().import_shadowing { - return - } - // First, check for conflicts between imports and `extern crate`s. if module.external_module_children .borrow() @@ -1805,7 +1801,7 @@ fn check_for_conflicts_between_imports_and_items(&mut self, crate in this module \ (maybe you meant `use {0}::*`?)", token::get_name(name).get()); - self.session.span_err(import_span, &msg[]); + span_err!(self.session, import_span, E0254, "{}", &msg[]); } Some(_) | None => {} } @@ -1827,7 +1823,7 @@ fn check_for_conflicts_between_imports_and_items(&mut self, let msg = format!("import `{}` conflicts with value \ in this module", token::get_name(name).get()); - self.session.span_err(import_span, &msg[]); + span_err!(self.session, import_span, E0255, "{}", &msg[]); if let Some(span) = value.value_span { self.session.span_note(span, "conflicting value here"); @@ -1845,7 +1841,7 @@ fn check_for_conflicts_between_imports_and_items(&mut self, let msg = format!("import `{}` conflicts with type in \ this module", token::get_name(name).get()); - self.session.span_err(import_span, &msg[]); + span_err!(self.session, import_span, E0256, "{}", &msg[]); if let Some(span) = ty.type_span { self.session.span_note(span, "note conflicting type here") @@ -1858,7 +1854,7 @@ fn check_for_conflicts_between_imports_and_items(&mut self, let msg = format!("inherent implementations \ are only allowed on types \ defined in the current module"); - self.session.span_err(span, &msg[]); + span_err!(self.session, span, E0257, "{}", &msg[]); self.session.span_note(import_span, "import from other module here") } @@ -1867,7 +1863,7 @@ fn check_for_conflicts_between_imports_and_items(&mut self, let msg = format!("import `{}` conflicts with existing \ submodule", token::get_name(name).get()); - self.session.span_err(import_span, &msg[]); + span_err!(self.session, import_span, E0258, "{}", &msg[]); if let Some(span) = ty.type_span { self.session.span_note(span, "note conflicting module here") @@ -1888,16 +1884,11 @@ fn check_for_conflicts_between_external_crates(&self, module: &Module, name: Name, span: Span) { - if self.session.features.borrow().import_shadowing { - return - } - if module.external_module_children.borrow().contains_key(&name) { - self.session - .span_err(span, - &format!("an external crate named `{}` has already \ + span_err!(self.session, span, E0259, + "an external crate named `{}` has already \ been imported into this module", - token::get_name(name).get())[]); + token::get_name(name).get()); } } @@ -1906,17 +1897,12 @@ fn check_for_conflicts_between_external_crates_and_items(&self, module: &Module, name: Name, span: Span) { - if self.session.features.borrow().import_shadowing { - return - } - if module.external_module_children.borrow().contains_key(&name) { - self.session - .span_err(span, - &format!("the name `{}` conflicts with an external \ + span_err!(self.session, span, E0260, + "the name `{}` conflicts with an external \ crate that has been imported into this \ module", - token::get_name(name).get())[]); + token::get_name(name).get()); } } @@ -1965,7 +1951,7 @@ fn search_parent_externals(needle: Name, module: &Rc) let module_name = self.module_to_string(&*search_module); let mut span = span; let msg = if "???" == &module_name[] { - span.hi = span.lo + Pos::from_uint(segment_name.get().len()); + span.hi = span.lo + Pos::from_usize(segment_name.get().len()); match search_parent_externals(name, &self.current_module) { @@ -2083,8 +2069,8 @@ fn resolve_module_path(&mut self, let msg = format!("Could not find `{}` in `{}`", // idx +- 1 to account for the // colons on either side - &mpath[(idx + 1)..], - &mpath[..(idx - 1)]); + &mpath[idx + 1..], + &mpath[..idx - 1]); return Failed(Some((span, msg))); }, None => { @@ -2760,7 +2746,7 @@ fn search_ribs(&self, for (i, rib) in ribs.iter().enumerate().rev() { match rib.bindings.get(&name).cloned() { Some(def_like) => { - return self.upvarify(&ribs[(i + 1)..], def_like, span); + return self.upvarify(&ribs[i + 1..], def_like, span); } None => { // Continue. @@ -2982,9 +2968,9 @@ fn resolve_item(&mut self, item: &Item) { }); } - ItemMac(..) => { + ItemExternCrate(_) | ItemUse(_) | ItemMac(..) => { // do nothing, these are just around to be encoded - } + } } } @@ -3525,6 +3511,26 @@ fn resolve_block(&mut self, block: &Block) { } } + // Check for imports appearing after non-item statements. + let mut found_non_item = false; + for statement in block.stmts.iter() { + if let ast::StmtDecl(ref declaration, _) = statement.node { + if let ast::DeclItem(ref i) = declaration.node { + match i.node { + ItemExternCrate(_) | ItemUse(_) if found_non_item => { + span_err!(self.session, i.span, E0154, + "imports are not allowed after non-item statements"); + } + _ => {} + } + } else { + found_non_item = true + } + } else { + found_non_item = true; + } + } + // Descend into the block. visit::walk_block(self, block); diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index dacf620cbd1..eedfc940751 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -178,7 +178,7 @@ pub fn build_link_meta(sess: &Session, krate: &ast::Crate, fn truncated_hash_result(symbol_hasher: &mut Sha256) -> String { let output = symbol_hasher.result_bytes(); // 64 bits should be enough to avoid collisions. - output.slice_to(8).to_hex().to_string() + output[.. 8].to_hex().to_string() } @@ -779,14 +779,14 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool, } if sess.opts.debugging_opts.print_link_args { - println!("{}", &cmd); + println!("{:?}", &cmd); } // May have not found libraries in the right formats. sess.abort_if_errors(); // Invoke the system linker - debug!("{}", &cmd); + debug!("{:?}", &cmd); let prog = time(sess.time_passes(), "running linker", (), |()| cmd.output()); match prog { Ok(prog) => { @@ -794,7 +794,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool, sess.err(&format!("linking with `{}` failed: {}", pname, prog.status)[]); - sess.note(&format!("{}", &cmd)[]); + sess.note(&format!("{:?}", &cmd)[]); let mut output = prog.error.clone(); output.push_all(&prog.output[]); sess.note(str::from_utf8(&output[]).unwrap()); @@ -1183,7 +1183,7 @@ fn add_static_crate(cmd: &mut Command, sess: &Session, tmpdir: &Path, // against the archive. if sess.lto() { let name = cratepath.filename_str().unwrap(); - let name = &name[3..(name.len() - 5)]; // chop off lib/.rlib + let name = &name[3..name.len() - 5]; // chop off lib/.rlib time(sess.time_passes(), &format!("altering {}.rlib", name)[], (), |()| { diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index c0b1492a784..590354ab54e 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -60,7 +60,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, let archive = ArchiveRO::open(&path).expect("wanted an rlib"); let file = path.filename_str().unwrap(); - let file = &file[3..(file.len() - 5)]; // chop off lib/.rlib + let file = &file[3..file.len() - 5]; // chop off lib/.rlib debug!("reading {}", file); for i in iter::count(0u, 1) { let bc_encoded = time(sess.time_passes(), @@ -201,7 +201,7 @@ fn extract_compressed_bytecode_size_v1(bc: &[u8]) -> u64 { } fn read_from_le_bytes(bytes: &[u8], position_in_bytes: uint) -> T { - let byte_data = &bytes[position_in_bytes..(position_in_bytes + mem::size_of::())]; + let byte_data = &bytes[position_in_bytes..position_in_bytes + mem::size_of::()]; let data = unsafe { *(byte_data.as_ptr() as *const T) }; diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index aa51b0c5ee2..b07c2060e69 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -67,11 +67,11 @@ pub fn write_output_file( output: &Path, file_type: llvm::FileType) { unsafe { - let output = CString::from_slice(output.as_vec()); + let output_c = CString::from_slice(output.as_vec()); let result = llvm::LLVMRustWriteOutputFile( - target, pm, m, output.as_ptr(), file_type); + target, pm, m, output_c.as_ptr(), file_type); if !result { - llvm_err(handler, "could not write output".to_string()); + llvm_err(handler, format!("could not write output to {}", output.display())); } } } @@ -716,7 +716,7 @@ pub fn run_passes(sess: &Session, cmd.args(&sess.target.target.options.post_link_args[]); if sess.opts.debugging_opts.print_link_args { - println!("{}", &cmd); + println!("{:?}", &cmd); } cmd.stdin(::std::io::process::Ignored) @@ -725,7 +725,7 @@ pub fn run_passes(sess: &Session, match cmd.status() { Ok(status) => { if !status.success() { - sess.err(&format!("linking of {} with `{}` failed", + sess.err(&format!("linking of {} with `{:?}` failed", output_path.display(), cmd)[]); sess.abort_if_errors(); } @@ -953,7 +953,7 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { cmd.arg("-c").arg("-o").arg(outputs.path(config::OutputTypeObject)) .arg(outputs.temp_path(config::OutputTypeAssembly)); - debug!("{}", &cmd); + debug!("{:?}", &cmd); match cmd.output() { Ok(prog) => { @@ -961,7 +961,7 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { sess.err(&format!("linking with `{}` failed: {}", pname, prog.status)[]); - sess.note(&format!("{}", &cmd)[]); + sess.note(&format!("{:?}", &cmd)[]); let mut note = prog.error.clone(); note.push_all(&prog.output[]); sess.note(str::from_utf8(¬e[]).unwrap()); diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index b12903c814c..4aec53711ad 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -157,7 +157,7 @@ fn write_sub_paths_truncated(&mut self, path: &ast::Path) { return; } - let sub_paths = sub_paths.slice(0, len-1); + let sub_paths = &sub_paths[.. (len-1)]; for &(ref span, ref qualname) in sub_paths.iter() { self.fmt.sub_mod_ref_str(path.span, *span, @@ -174,7 +174,7 @@ fn write_sub_path_trait_truncated(&mut self, path: &ast::Path) { if len <= 1 { return; } - let sub_paths = sub_paths.slice_to(len-1); + let sub_paths = &sub_paths[.. (len-1)]; // write the trait part of the sub-path let (ref span, ref qualname) = sub_paths[len-2]; @@ -186,7 +186,7 @@ fn write_sub_path_trait_truncated(&mut self, path: &ast::Path) { if len <= 2 { return; } - let sub_paths = &sub_paths[..(len-2)]; + let sub_paths = &sub_paths[..len-2]; for &(ref span, ref qualname) in sub_paths.iter() { self.fmt.sub_mod_ref_str(path.span, *span, @@ -1037,6 +1037,110 @@ fn visit_item(&mut self, item: &ast::Item) { } match item.node { + ast::ItemUse(ref use_item) => { + match use_item.node { + ast::ViewPathSimple(ident, ref path) => { + let sub_span = self.span.span_for_last_ident(path.span); + let mod_id = match self.lookup_type_ref(item.id) { + Some(def_id) => { + match self.lookup_def_kind(item.id, path.span) { + Some(kind) => self.fmt.ref_str(kind, + path.span, + sub_span, + def_id, + self.cur_scope), + None => {}, + } + Some(def_id) + }, + None => None, + }; + + // 'use' always introduces an alias, if there is not an explicit + // one, there is an implicit one. + let sub_span = + match self.span.sub_span_after_keyword(use_item.span, keywords::As) { + Some(sub_span) => Some(sub_span), + None => sub_span, + }; + + self.fmt.use_alias_str(path.span, + sub_span, + item.id, + mod_id, + get_ident(ident).get(), + self.cur_scope); + self.write_sub_paths_truncated(path); + } + ast::ViewPathGlob(ref path) => { + // Make a comma-separated list of names of imported modules. + let mut name_string = String::new(); + let glob_map = &self.analysis.glob_map; + let glob_map = glob_map.as_ref().unwrap(); + if glob_map.contains_key(&item.id) { + for n in glob_map[item.id].iter() { + if name_string.len() > 0 { + name_string.push_str(", "); + } + name_string.push_str(n.as_str()); + } + } + + let sub_span = self.span.sub_span_of_token(path.span, + token::BinOp(token::Star)); + self.fmt.use_glob_str(path.span, + sub_span, + item.id, + name_string.as_slice(), + self.cur_scope); + self.write_sub_paths(path); + } + ast::ViewPathList(ref path, ref list) => { + for plid in list.iter() { + match plid.node { + ast::PathListIdent { id, .. } => { + match self.lookup_type_ref(id) { + Some(def_id) => + match self.lookup_def_kind(id, plid.span) { + Some(kind) => { + self.fmt.ref_str( + kind, plid.span, + Some(plid.span), + def_id, self.cur_scope); + } + None => () + }, + None => () + } + }, + ast::PathListMod { .. } => () + } + } + + self.write_sub_paths(path); + } + } + } + ast::ItemExternCrate(ref s) => { + let name = get_ident(item.ident); + let name = name.get(); + let s = match *s { + Some((ref s, _)) => s.get().to_string(), + None => name.to_string(), + }; + let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Crate); + let cnum = match self.sess.cstore.find_extern_mod_stmt_cnum(item.id) { + Some(cnum) => cnum, + None => 0, + }; + self.fmt.extern_crate_str(item.span, + sub_span, + item.id, + cnum, + name, + &s[], + self.cur_scope); + } ast::ItemFn(ref decl, _, _, ref ty_params, ref body) => self.process_fn(item, &**decl, ty_params, &**body), ast::ItemStatic(ref typ, mt, ref expr) => @@ -1160,119 +1264,6 @@ fn visit_trait_item(&mut self, tm: &ast::TraitItem) { } } - fn visit_view_item(&mut self, i: &ast::ViewItem) { - if generated_code(i.span) { - return - } - - match i.node { - ast::ViewItemUse(ref item) => { - match item.node { - ast::ViewPathSimple(ident, ref path, id) => { - let sub_span = self.span.span_for_last_ident(path.span); - let mod_id = match self.lookup_type_ref(id) { - Some(def_id) => { - match self.lookup_def_kind(id, path.span) { - Some(kind) => self.fmt.ref_str(kind, - path.span, - sub_span, - def_id, - self.cur_scope), - None => {}, - } - Some(def_id) - }, - None => None, - }; - - // 'use' always introduces an alias, if there is not an explicit - // one, there is an implicit one. - let sub_span = - match self.span.sub_span_after_keyword(item.span, keywords::As) { - Some(sub_span) => Some(sub_span), - None => sub_span, - }; - - self.fmt.use_alias_str(path.span, - sub_span, - id, - mod_id, - get_ident(ident).get(), - self.cur_scope); - self.write_sub_paths_truncated(path); - } - ast::ViewPathGlob(ref path, id) => { - // Make a comma-separated list of names of imported modules. - let mut name_string = String::new(); - let glob_map = &self.analysis.glob_map; - let glob_map = glob_map.as_ref().unwrap(); - if glob_map.contains_key(&id) { - for n in glob_map[id].iter() { - if name_string.len() > 0 { - name_string.push_str(", "); - } - name_string.push_str(n.as_str()); - } - } - - let sub_span = self.span.sub_span_of_token(path.span, - token::BinOp(token::Star)); - self.fmt.use_glob_str(path.span, - sub_span, - id, - name_string.as_slice(), - self.cur_scope); - self.write_sub_paths(path); - } - ast::ViewPathList(ref path, ref list, _) => { - for plid in list.iter() { - match plid.node { - ast::PathListIdent { id, .. } => { - match self.lookup_type_ref(id) { - Some(def_id) => - match self.lookup_def_kind(id, plid.span) { - Some(kind) => { - self.fmt.ref_str( - kind, plid.span, - Some(plid.span), - def_id, self.cur_scope); - } - None => () - }, - None => () - } - }, - ast::PathListMod { .. } => () - } - } - - self.write_sub_paths(path); - } - } - }, - ast::ViewItemExternCrate(ident, ref s, id) => { - let name = get_ident(ident); - let name = name.get(); - let s = match *s { - Some((ref s, _)) => s.get().to_string(), - None => name.to_string(), - }; - let sub_span = self.span.sub_span_after_keyword(i.span, keywords::Crate); - let cnum = match self.sess.cstore.find_extern_mod_stmt_cnum(id) { - Some(cnum) => cnum, - None => 0, - }; - self.fmt.extern_crate_str(i.span, - sub_span, - id, - cnum, - name, - &s[], - self.cur_scope); - }, - } - } - fn visit_ty(&mut self, t: &ast::Ty) { if generated_code(t.span) { return diff --git a/src/librustc_trans/save/span_utils.rs b/src/librustc_trans/save/span_utils.rs index 77343612ac8..97b3cda006b 100644 --- a/src/librustc_trans/save/span_utils.rs +++ b/src/librustc_trans/save/span_utils.rs @@ -40,8 +40,8 @@ pub fn extent_str(&self, span: Span) -> String { format!("file_name,{},file_line,{},file_col,{},extent_start,{},extent_start_bytes,{},\ file_line_end,{},file_col_end,{},extent_end,{},extent_end_bytes,{}", lo_loc.file.name, - lo_loc.line, lo_loc.col.to_uint(), lo_pos.to_uint(), lo_pos_byte.to_uint(), - hi_loc.line, hi_loc.col.to_uint(), hi_pos.to_uint(), hi_pos_byte.to_uint()) + lo_loc.line, lo_loc.col.to_usize(), lo_pos.to_usize(), lo_pos_byte.to_usize(), + hi_loc.line, hi_loc.col.to_usize(), hi_pos.to_usize(), hi_pos_byte.to_usize()) } // sub_span starts at span.lo, so we need to adjust the positions etc. diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 9f3c55d4f68..dcb0b0ef4ea 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -208,10 +208,10 @@ use trans::common::*; use trans::consts; use trans::datum::*; +use trans::debuginfo::{self, DebugLoc, ToDebugLoc}; use trans::expr::{self, Dest}; use trans::tvec; use trans::type_of; -use trans::debuginfo; use middle::ty::{self, Ty}; use session::config::FullDebugInfo; use util::common::indenter; @@ -472,7 +472,7 @@ fn enter_default<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, enter_match(bcx, dm, m, col, val, |pats| { if pat_is_binding_or_wild(dm, &*pats[col]) { let mut r = pats[..col].to_vec(); - r.push_all(&pats[(col + 1)..]); + r.push_all(&pats[col + 1..]); Some(r) } else { None @@ -632,7 +632,7 @@ fn bind_subslice_pat(bcx: Block, let slice_begin = InBoundsGEP(bcx, base, &[C_uint(bcx.ccx(), offset_left)]); let slice_len_offset = C_uint(bcx.ccx(), offset_left + offset_right); - let slice_len = Sub(bcx, len, slice_len_offset); + let slice_len = Sub(bcx, len, slice_len_offset, DebugLoc::None); let slice_ty = ty::mk_slice(bcx.tcx(), bcx.tcx().mk_region(ty::ReStatic), ty::mt {ty: vt.unit_ty, mutbl: ast::MutImmutable}); @@ -656,7 +656,7 @@ fn extract_vec_elems<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, elems.extend(range(0, before).map(|i| GEPi(bcx, base, &[i]))); elems.extend(range(0, after).rev().map(|i| { InBoundsGEP(bcx, base, &[ - Sub(bcx, len, C_uint(bcx.ccx(), i + 1)) + Sub(bcx, len, C_uint(bcx.ccx(), i + 1), DebugLoc::None) ]) })); ExtractedBlock { vals: elems, bcx: bcx } @@ -731,7 +731,7 @@ fn handle_fail(&self, bcx: Block) { Infallible => panic!("attempted to panic in a non-panicking panic handler!"), JumpToBasicBlock(basic_block) => - Br(bcx, basic_block), + Br(bcx, basic_block, DebugLoc::None), Unreachable => build::Unreachable(bcx) } @@ -889,7 +889,7 @@ fn compile_guard<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } } - with_cond(bcx, Not(bcx, val), |bcx| { + with_cond(bcx, Not(bcx, val, guard_expr.debug_loc()), |bcx| { // Guard does not match: remove all bindings from the lllocals table for (_, &binding_info) in data.bindings_map.iter() { call_lifetime_end(bcx, binding_info.llmatch); @@ -966,7 +966,7 @@ fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } _ => () } - Br(bcx, data.bodycx.llbb); + Br(bcx, data.bodycx.llbb, DebugLoc::None); } } } @@ -983,7 +983,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let dm = &tcx.def_map; let mut vals_left = vals[0u..col].to_vec(); - vals_left.push_all(&vals[(col + 1u)..]); + vals_left.push_all(&vals[col + 1u..]); let ccx = bcx.fcx.ccx; // Find a real id (we're adding placeholder wildcard patterns, but @@ -1096,7 +1096,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, if !exhaustive || i + 1 < len { opt_cx = bcx.fcx.new_temp_block("match_case"); match kind { - Single => Br(bcx, opt_cx.llbb), + Single => Br(bcx, opt_cx.llbb, DebugLoc::None), Switch => { match opt.trans(bcx) { SingleResult(r) => { @@ -1131,7 +1131,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, compare_scalar_types( bcx, test_val, vend, t, ast::BiLe); - Result::new(bcx, And(bcx, llge, llle)) + Result::new(bcx, And(bcx, llge, llle, DebugLoc::None)) } LowerBound(Result { bcx, val }) => { compare_scalar_types(bcx, test_val, val, t, ast::BiGe) @@ -1149,12 +1149,12 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, if i + 1 < len && (guarded || multi_pats || kind == CompareSliceLength) { branch_chk = Some(JumpToBasicBlock(bcx.llbb)); } - CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb); + CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb, DebugLoc::None); } _ => () } } else if kind == Compare || kind == CompareSliceLength { - Br(bcx, else_cx.llbb); + Br(bcx, else_cx.llbb, DebugLoc::None); } let mut size = 0u; @@ -1194,7 +1194,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, // Compile the fall-through case, if any if !exhaustive && kind != Single { if kind == Compare || kind == CompareSliceLength { - Br(bcx, else_cx.llbb); + Br(bcx, else_cx.llbb, DebugLoc::None); } match chk { // If there is only one default arm left, move on to the next diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index 92883371ec9..c98515cff68 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -62,6 +62,7 @@ use trans::cleanup::CleanupMethods; use trans::common::*; use trans::datum; +use trans::debuginfo::DebugLoc; use trans::machine; use trans::monomorphize; use trans::type_::Type; @@ -979,7 +980,7 @@ pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, let variant_value = PointerCast(variant_cx, value, real_ty.ptr_to()); variant_cx = f(variant_cx, case, variant_value); - Br(variant_cx, bcx_next.llbb); + Br(variant_cx, bcx_next.llbb, DebugLoc::None); } bcx_next diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index eed61ae59a2..572dfd165ee 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -57,7 +57,7 @@ use trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_integral}; use trans::common::{C_null, C_struct_in_context, C_u64, C_u8, C_undef}; use trans::common::{CrateContext, ExternMap, FunctionContext}; -use trans::common::{NodeInfo, Result}; +use trans::common::{Result}; use trans::common::{node_id_type, return_type_is_void}; use trans::common::{tydesc_info, type_is_immediate}; use trans::common::{type_is_zero_size, val_ty}; @@ -66,7 +66,7 @@ use trans::context::SharedCrateContext; use trans::controlflow; use trans::datum; -use trans::debuginfo; +use trans::debuginfo::{self, DebugLoc}; use trans::expr; use trans::foreign; use trans::glue; @@ -362,18 +362,6 @@ pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId, } } -// Returns a pointer to the body for the box. The box may be an opaque -// box. The result will be casted to the type of body_t, if it is statically -// known. -pub fn at_box_body<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - body_t: Ty<'tcx>, boxptr: ValueRef) -> ValueRef { - let _icx = push_ctxt("at_box_body"); - let ccx = bcx.ccx(); - let ty = Type::at_box(ccx, type_of(ccx, body_t)); - let boxptr = PointerCast(bcx, boxptr, ty.ptr_to()); - GEPi(bcx, boxptr, &[0u, abi::BOX_FIELD_BODY]) -} - fn require_alloc_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, info_ty: Ty<'tcx>, it: LangItem) -> ast::DefId { match bcx.tcx().lang_items.require(it) { @@ -792,7 +780,7 @@ fn iter_variant<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>, &**variant, substs, &mut f); - Br(variant_cx, next_cx.llbb); + Br(variant_cx, next_cx.llbb, DebugLoc::None); } cx = next_cx; } @@ -957,7 +945,7 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, llfn: ValueRef, llargs: &[ValueRef], fn_ty: Ty<'tcx>, - call_info: Option) + debug_loc: DebugLoc) -> (ValueRef, Block<'blk, 'tcx>) { let _icx = push_ctxt("invoke_"); if bcx.unreachable.get() { @@ -983,17 +971,13 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let normal_bcx = bcx.fcx.new_temp_block("normal-return"); let landing_pad = bcx.fcx.get_landing_pad(); - match call_info { - Some(info) => debuginfo::set_source_location(bcx.fcx, info.id, info.span), - None => debuginfo::clear_source_location(bcx.fcx) - }; - let llresult = Invoke(bcx, llfn, &llargs[], normal_bcx.llbb, landing_pad, - Some(attributes)); + Some(attributes), + debug_loc); return (llresult, normal_bcx); } else { debug!("calling {} at {:?}", bcx.val_to_string(llfn), bcx.llbb); @@ -1001,12 +985,11 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, debug!("arg: {}", bcx.val_to_string(llarg)); } - match call_info { - Some(info) => debuginfo::set_source_location(bcx.fcx, info.id, info.span), - None => debuginfo::clear_source_location(bcx.fcx) - }; - - let llresult = Call(bcx, llfn, &llargs[], Some(attributes)); + let llresult = Call(bcx, + llfn, + &llargs[], + Some(attributes), + debug_loc); return (llresult, bcx); } } @@ -1094,10 +1077,10 @@ pub fn with_cond<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, let fcx = bcx.fcx; let next_cx = fcx.new_temp_block("next"); let cond_cx = fcx.new_temp_block("cond"); - CondBr(bcx, val, cond_cx.llbb, next_cx.llbb); + CondBr(bcx, val, cond_cx.llbb, next_cx.llbb, DebugLoc::None); let after_cx = f(cond_cx); if !after_cx.terminated.get() { - Br(after_cx, next_cx.llbb); + Br(after_cx, next_cx.llbb, DebugLoc::None); } next_cx } @@ -1113,7 +1096,7 @@ pub fn call_lifetime_start(cx: Block, ptr: ValueRef) { let llsize = C_u64(ccx, machine::llsize_of_alloc(ccx, val_ty(ptr).element_type())); let ptr = PointerCast(cx, ptr, Type::i8p(ccx)); let lifetime_start = ccx.get_intrinsic(&"llvm.lifetime.start"); - Call(cx, lifetime_start, &[llsize, ptr], None); + Call(cx, lifetime_start, &[llsize, ptr], None, DebugLoc::None); } pub fn call_lifetime_end(cx: Block, ptr: ValueRef) { @@ -1127,7 +1110,7 @@ pub fn call_lifetime_end(cx: Block, ptr: ValueRef) { let llsize = C_u64(ccx, machine::llsize_of_alloc(ccx, val_ty(ptr).element_type())); let ptr = PointerCast(cx, ptr, Type::i8p(ccx)); let lifetime_end = ccx.get_intrinsic(&"llvm.lifetime.end"); - Call(cx, lifetime_end, &[llsize, ptr], None); + Call(cx, lifetime_end, &[llsize, ptr], None, DebugLoc::None); } pub fn call_memcpy(cx: Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) { @@ -1144,7 +1127,7 @@ pub fn call_memcpy(cx: Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, a let size = IntCast(cx, n_bytes, ccx.int_type()); let align = C_i32(ccx, align as i32); let volatile = C_bool(ccx, false); - Call(cx, memcpy, &[dst_ptr, src_ptr, size, align, volatile], None); + Call(cx, memcpy, &[dst_ptr, src_ptr, size, align, volatile], None, DebugLoc::None); } pub fn memcpy_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, @@ -1697,13 +1680,14 @@ fn copy_unboxed_closure_args_to_allocas<'blk, 'tcx>( // and builds the return block. pub fn finish_fn<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>, last_bcx: Block<'blk, 'tcx>, - retty: ty::FnOutput<'tcx>) { + retty: ty::FnOutput<'tcx>, + ret_debug_loc: DebugLoc) { let _icx = push_ctxt("finish_fn"); let ret_cx = match fcx.llreturn.get() { Some(llreturn) => { if !last_bcx.terminated.get() { - Br(last_bcx, llreturn); + Br(last_bcx, llreturn, DebugLoc::None); } raw_block(fcx, false, llreturn) } @@ -1713,7 +1697,7 @@ pub fn finish_fn<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>, // This shouldn't need to recompute the return type, // as new_fn_ctxt did it already. let substd_retty = fcx.monomorphize(&retty); - build_return_block(fcx, ret_cx, substd_retty); + build_return_block(fcx, ret_cx, substd_retty, ret_debug_loc); debuginfo::clear_source_location(fcx); fcx.cleanup(); @@ -1722,10 +1706,11 @@ pub fn finish_fn<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>, // Builds the return block for a function. pub fn build_return_block<'blk, 'tcx>(fcx: &FunctionContext<'blk, 'tcx>, ret_cx: Block<'blk, 'tcx>, - retty: ty::FnOutput<'tcx>) { + retty: ty::FnOutput<'tcx>, + ret_debug_location: DebugLoc) { if fcx.llretslotptr.get().is_none() || (!fcx.needs_ret_allocas && fcx.caller_expects_out_pointer) { - return RetVoid(ret_cx); + return RetVoid(ret_cx, ret_debug_location); } let retslot = if fcx.needs_ret_allocas { @@ -1755,9 +1740,9 @@ pub fn build_return_block<'blk, 'tcx>(fcx: &FunctionContext<'blk, 'tcx>, if let ty::FnConverging(retty) = retty { store_ty(ret_cx, retval, get_param(fcx.llfn, 0), retty); } - RetVoid(ret_cx) + RetVoid(ret_cx, ret_debug_location) } else { - Ret(ret_cx, retval) + Ret(ret_cx, retval, ret_debug_location) } } // Otherwise, copy the return value to the ret slot @@ -1765,16 +1750,16 @@ pub fn build_return_block<'blk, 'tcx>(fcx: &FunctionContext<'blk, 'tcx>, ty::FnConverging(retty) => { if fcx.caller_expects_out_pointer { memcpy_ty(ret_cx, get_param(fcx.llfn, 0), retslot, retty); - RetVoid(ret_cx) + RetVoid(ret_cx, ret_debug_location) } else { - Ret(ret_cx, load_ty(ret_cx, retslot, retty)) + Ret(ret_cx, load_ty(ret_cx, retslot, retty), ret_debug_location) } } ty::FnDiverging => { if fcx.caller_expects_out_pointer { - RetVoid(ret_cx) + RetVoid(ret_cx, ret_debug_location) } else { - Ret(ret_cx, C_undef(Type::nil(fcx.ccx))) + Ret(ret_cx, C_undef(Type::nil(fcx.ccx)), ret_debug_location) } } } @@ -1832,7 +1817,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, .map(|arg| node_id_type(bcx, arg.id)) .collect::>(); let monomorphized_arg_types = match closure_env.kind { - closure::NotClosure | closure::BoxedClosure(..) => { + closure::NotClosure => { monomorphized_arg_types } @@ -1859,7 +1844,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, }; bcx = match closure_env.kind { - closure::NotClosure | closure::BoxedClosure(..) => { + closure::NotClosure => { copy_args_to_allocas(bcx, arg_scope, &decl.inputs[], @@ -1905,7 +1890,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, match fcx.llreturn.get() { Some(_) => { - Br(bcx, fcx.return_exit_block()); + Br(bcx, fcx.return_exit_block(), DebugLoc::None); fcx.pop_custom_cleanup_scope(arg_scope); } None => { @@ -1924,8 +1909,11 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } } + let ret_debug_loc = DebugLoc::At(fn_cleanup_debug_loc.id, + fn_cleanup_debug_loc.span); + // Insert the mandatory first few basic blocks before lltop. - finish_fn(&fcx, bcx, output_type); + finish_fn(&fcx, bcx, output_type, ret_debug_loc); } // trans_fn: creates an LLVM function corresponding to a source language @@ -1977,7 +1965,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, disr: ty::Disr, args: callee::CallArgs, dest: expr::Dest, - call_info: Option) + debug_loc: DebugLoc) -> Result<'blk, 'tcx> { let ccx = bcx.fcx.ccx; @@ -2016,7 +2004,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, &fields[], None, expr::SaveIn(llresult), - call_info); + debug_loc); } _ => ccx.sess().bug("expected expr as arguments for variant/struct tuple constructor") } @@ -2027,7 +2015,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let bcx = match dest { expr::SaveIn(_) => bcx, expr::Ignore => { - glue::drop_ty(bcx, llresult, result_ty, call_info) + glue::drop_ty(bcx, llresult, result_ty, debug_loc) } }; @@ -2094,7 +2082,7 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx adt::trans_set_discr(bcx, &*repr, dest, disr); } - finish_fn(&fcx, bcx, result_ty); + finish_fn(&fcx, bcx, result_ty, DebugLoc::None); } fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span, id: ast::NodeId) { diff --git a/src/librustc_trans/trans/build.rs b/src/librustc_trans/trans/build.rs index 1f77f625c9d..7acac5a12eb 100644 --- a/src/librustc_trans/trans/build.rs +++ b/src/librustc_trans/trans/build.rs @@ -20,6 +20,7 @@ use trans::builder::Builder; use trans::type_::Type; +use trans::debuginfo::DebugLoc; use libc::{c_uint, c_char}; @@ -48,41 +49,59 @@ pub fn B<'blk, 'tcx>(cx: Block<'blk, 'tcx>) -> Builder<'blk, 'tcx> { // for (panic/break/return statements, call to diverging functions, etc), and // further instructions to the block should simply be ignored. -pub fn RetVoid(cx: Block) { - if cx.unreachable.get() { return; } +pub fn RetVoid(cx: Block, debug_loc: DebugLoc) { + if cx.unreachable.get() { + return; + } check_not_terminated(cx); terminate(cx, "RetVoid"); + debug_loc.apply(cx.fcx); B(cx).ret_void(); } -pub fn Ret(cx: Block, v: ValueRef) { - if cx.unreachable.get() { return; } +pub fn Ret(cx: Block, v: ValueRef, debug_loc: DebugLoc) { + if cx.unreachable.get() { + return; + } check_not_terminated(cx); terminate(cx, "Ret"); + debug_loc.apply(cx.fcx); B(cx).ret(v); } -pub fn AggregateRet(cx: Block, ret_vals: &[ValueRef]) { - if cx.unreachable.get() { return; } +pub fn AggregateRet(cx: Block, + ret_vals: &[ValueRef], + debug_loc: DebugLoc) { + if cx.unreachable.get() { + return; + } check_not_terminated(cx); terminate(cx, "AggregateRet"); + debug_loc.apply(cx.fcx); B(cx).aggregate_ret(ret_vals); } -pub fn Br(cx: Block, dest: BasicBlockRef) { - if cx.unreachable.get() { return; } +pub fn Br(cx: Block, dest: BasicBlockRef, debug_loc: DebugLoc) { + if cx.unreachable.get() { + return; + } check_not_terminated(cx); terminate(cx, "Br"); + debug_loc.apply(cx.fcx); B(cx).br(dest); } pub fn CondBr(cx: Block, if_: ValueRef, then: BasicBlockRef, - else_: BasicBlockRef) { - if cx.unreachable.get() { return; } + else_: BasicBlockRef, + debug_loc: DebugLoc) { + if cx.unreachable.get() { + return; + } check_not_terminated(cx); terminate(cx, "CondBr"); + debug_loc.apply(cx.fcx); B(cx).cond_br(if_, then, else_); } @@ -101,10 +120,16 @@ pub fn AddCase(s: ValueRef, on_val: ValueRef, dest: BasicBlockRef) { } } -pub fn IndirectBr(cx: Block, addr: ValueRef, num_dests: uint) { - if cx.unreachable.get() { return; } +pub fn IndirectBr(cx: Block, + addr: ValueRef, + num_dests: uint, + debug_loc: DebugLoc) { + if cx.unreachable.get() { + return; + } check_not_terminated(cx); terminate(cx, "IndirectBr"); + debug_loc.apply(cx.fcx); B(cx).indirect_br(addr, num_dests); } @@ -113,7 +138,8 @@ pub fn Invoke(cx: Block, args: &[ValueRef], then: BasicBlockRef, catch: BasicBlockRef, - attributes: Option) + attributes: Option, + debug_loc: DebugLoc) -> ValueRef { if cx.unreachable.get() { return C_null(Type::i8(cx.ccx())); @@ -123,6 +149,7 @@ pub fn Invoke(cx: Block, debug!("Invoke({} with arguments ({}))", cx.val_to_string(fn_), args.iter().map(|a| cx.val_to_string(*a)).collect::>().connect(", ")); + debug_loc.apply(cx.fcx); B(cx).invoke(fn_, args, then, catch, attributes) } @@ -143,176 +170,378 @@ pub fn _Undef(val: ValueRef) -> ValueRef { } /* Arithmetic */ -pub fn Add(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn Add(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).add(lhs, rhs) } -pub fn NSWAdd(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn NSWAdd(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).nswadd(lhs, rhs) } -pub fn NUWAdd(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn NUWAdd(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).nuwadd(lhs, rhs) } -pub fn FAdd(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn FAdd(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).fadd(lhs, rhs) } -pub fn Sub(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn Sub(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).sub(lhs, rhs) } -pub fn NSWSub(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn NSWSub(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).nswsub(lhs, rhs) } -pub fn NUWSub(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn NUWSub(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).nuwsub(lhs, rhs) } -pub fn FSub(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn FSub(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).fsub(lhs, rhs) } -pub fn Mul(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn Mul(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).mul(lhs, rhs) } -pub fn NSWMul(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn NSWMul(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).nswmul(lhs, rhs) } -pub fn NUWMul(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn NUWMul(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).nuwmul(lhs, rhs) } -pub fn FMul(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn FMul(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).fmul(lhs, rhs) } -pub fn UDiv(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn UDiv(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).udiv(lhs, rhs) } -pub fn SDiv(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn SDiv(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).sdiv(lhs, rhs) } -pub fn ExactSDiv(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn ExactSDiv(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).exactsdiv(lhs, rhs) } -pub fn FDiv(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn FDiv(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).fdiv(lhs, rhs) } -pub fn URem(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn URem(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).urem(lhs, rhs) } -pub fn SRem(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn SRem(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).srem(lhs, rhs) } -pub fn FRem(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn FRem(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).frem(lhs, rhs) } -pub fn Shl(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn Shl(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).shl(lhs, rhs) } -pub fn LShr(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn LShr(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).lshr(lhs, rhs) } -pub fn AShr(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn AShr(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).ashr(lhs, rhs) } -pub fn And(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn And(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).and(lhs, rhs) } -pub fn Or(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn Or(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).or(lhs, rhs) } -pub fn Xor(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } +pub fn Xor(cx: Block, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).xor(lhs, rhs) } -pub fn BinOp(cx: Block, op: Opcode, lhs: ValueRef, rhs: ValueRef) +pub fn BinOp(cx: Block, + op: Opcode, + lhs: ValueRef, + rhs: ValueRef, + debug_loc: DebugLoc) -> ValueRef { - if cx.unreachable.get() { return _Undef(lhs); } + if cx.unreachable.get() { + return _Undef(lhs); + } + debug_loc.apply(cx.fcx); B(cx).binop(op, lhs, rhs) } -pub fn Neg(cx: Block, v: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(v); } +pub fn Neg(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef { + if cx.unreachable.get() { + return _Undef(v); + } + debug_loc.apply(cx.fcx); B(cx).neg(v) } -pub fn NSWNeg(cx: Block, v: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(v); } +pub fn NSWNeg(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef { + if cx.unreachable.get() { + return _Undef(v); + } + debug_loc.apply(cx.fcx); B(cx).nswneg(v) } -pub fn NUWNeg(cx: Block, v: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(v); } +pub fn NUWNeg(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef { + if cx.unreachable.get() { + return _Undef(v); + } + debug_loc.apply(cx.fcx); B(cx).nuwneg(v) } -pub fn FNeg(cx: Block, v: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(v); } +pub fn FNeg(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef { + if cx.unreachable.get() { + return _Undef(v); + } + debug_loc.apply(cx.fcx); B(cx).fneg(v) } -pub fn Not(cx: Block, v: ValueRef) -> ValueRef { - if cx.unreachable.get() { return _Undef(v); } +pub fn Not(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef { + if cx.unreachable.get() { + return _Undef(v); + } + debug_loc.apply(cx.fcx); B(cx).not(v) } /* Memory */ -pub fn Malloc(cx: Block, ty: Type) -> ValueRef { +pub fn Malloc(cx: Block, ty: Type, debug_loc: DebugLoc) -> ValueRef { unsafe { if cx.unreachable.get() { return llvm::LLVMGetUndef(Type::i8p(cx.ccx()).to_ref()); } + debug_loc.apply(cx.fcx); B(cx).malloc(ty) } } -pub fn ArrayMalloc(cx: Block, ty: Type, val: ValueRef) -> ValueRef { +pub fn ArrayMalloc(cx: Block, + ty: Type, + val: ValueRef, + debug_loc: DebugLoc) -> ValueRef { unsafe { if cx.unreachable.get() { return llvm::LLVMGetUndef(Type::i8p(cx.ccx()).to_ref()); } + debug_loc.apply(cx.fcx); B(cx).array_malloc(ty, val) } } @@ -327,6 +556,7 @@ pub fn Alloca(cx: Block, ty: Type, name: &str) -> ValueRef { pub fn AllocaFcx(fcx: &FunctionContext, ty: Type, name: &str) -> ValueRef { let b = fcx.ccx.builder(); b.position_before(fcx.alloca_insert_pt.get().unwrap()); + DebugLoc::None.apply(fcx); b.alloca(ty, name) } @@ -335,6 +565,7 @@ pub fn ArrayAlloca(cx: Block, ty: Type, val: ValueRef) -> ValueRef { if cx.unreachable.get() { return llvm::LLVMGetUndef(ty.ptr_to().to_ref()); } let b = cx.fcx.ccx.builder(); b.position_before(cx.fcx.alloca_insert_pt.get().unwrap()); + DebugLoc::None.apply(cx.fcx); b.array_alloca(ty, val) } } @@ -680,9 +911,16 @@ pub fn InlineAsmCall(cx: Block, asm: *const c_char, cons: *const c_char, B(cx).inline_asm_call(asm, cons, inputs, output, volatile, alignstack, dia) } -pub fn Call(cx: Block, fn_: ValueRef, args: &[ValueRef], - attributes: Option) -> ValueRef { - if cx.unreachable.get() { return _UndefReturn(cx, fn_); } +pub fn Call(cx: Block, + fn_: ValueRef, + args: &[ValueRef], + attributes: Option, + debug_loc: DebugLoc) + -> ValueRef { + if cx.unreachable.get() { + return _UndefReturn(cx, fn_); + } + debug_loc.apply(cx.fcx); B(cx).call(fn_, args, attributes) } diff --git a/src/librustc_trans/trans/cabi_x86_64.rs b/src/librustc_trans/trans/cabi_x86_64.rs index 980a70256e9..3c0530bbb9a 100644 --- a/src/librustc_trans/trans/cabi_x86_64.rs +++ b/src/librustc_trans/trans/cabi_x86_64.rs @@ -361,7 +361,7 @@ fn llvec_len(cls: &[RegClass]) -> uint { } _ => unreachable!(), }; - let vec_len = llvec_len(&cls[(i + 1u)..]); + let vec_len = llvec_len(&cls[i + 1u..]); let vec_ty = Type::vector(&elt_ty, vec_len as u64 * elts_per_word); tys.push(vec_ty); i += vec_len; diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 11006f37531..7ed4727404e 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -40,6 +40,7 @@ use trans::common::*; use trans::consts; use trans::datum::*; +use trans::debuginfo::{DebugLoc, ToDebugLoc}; use trans::expr; use trans::glue; use trans::inline; @@ -356,7 +357,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>( ArgVals(&llargs[]), dest).bcx; - finish_fn(&fcx, bcx, sig.output); + finish_fn(&fcx, bcx, sig.output, DebugLoc::None); ccx.fn_pointer_shims().borrow_mut().insert(bare_fn_ty, llfn); @@ -646,7 +647,7 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, /// For non-lang items, `dest` is always Some, and hence the result is written into memory /// somewhere. Nonetheless we return the actual return value of the function. pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, - call_info: Option, + call_info: Option, callee_ty: Ty<'tcx>, get_callee: F, args: CallArgs<'a, 'tcx>, @@ -703,7 +704,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, disr, args, dest.unwrap(), - call_info); + call_info.debug_loc()); } }; @@ -781,7 +782,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, llfn, &llargs[], callee_ty, - call_info); + call_info.debug_loc()); bcx = b; llresult = llret; @@ -828,7 +829,10 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, match (dest, opt_llretslot, ret_ty) { (Some(expr::Ignore), Some(llretslot), ty::FnConverging(ret_ty)) => { // drop the value if it is not being saved. - bcx = glue::drop_ty(bcx, llretslot, ret_ty, call_info); + bcx = glue::drop_ty(bcx, + llretslot, + ret_ty, + call_info.debug_loc()); call_lifetime_end(bcx, llretslot); } _ => {} diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index 5658889aaf3..a25f4f778ab 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -21,8 +21,8 @@ use trans::build; use trans::callee; use trans::common; -use trans::common::{Block, FunctionContext, ExprId, NodeInfo}; -use trans::debuginfo; +use trans::common::{Block, FunctionContext, ExprId, NodeIdAndSpan}; +use trans::debuginfo::{DebugLoc, ToDebugLoc}; use trans::glue; use middle::region; use trans::type_::Type; @@ -44,7 +44,7 @@ pub struct CleanupScope<'blk, 'tcx: 'blk> { // The debug location any drop calls generated for this scope will be // associated with. - debug_loc: Option, + debug_loc: DebugLoc, cached_early_exits: Vec, cached_landing_pad: Option, @@ -65,7 +65,7 @@ pub enum CleanupScopeKind<'blk, 'tcx: 'blk> { LoopScopeKind(ast::NodeId, [Block<'blk, 'tcx>; EXIT_MAX]) } -impl<'blk, 'tcx: 'blk> fmt::Show for CleanupScopeKind<'blk, 'tcx> { +impl<'blk, 'tcx: 'blk> fmt::Debug for CleanupScopeKind<'blk, 'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { CustomScopeKind => write!(f, "CustomScopeKind"), @@ -100,7 +100,7 @@ pub trait Cleanup<'tcx> { fn is_lifetime_end(&self) -> bool; fn trans<'blk>(&self, bcx: Block<'blk, 'tcx>, - debug_loc: Option) + debug_loc: DebugLoc) -> Block<'blk, 'tcx>; } @@ -114,7 +114,7 @@ pub enum ScopeId { impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { /// Invoked when we start to trans the code contained within a new cleanup scope. - fn push_ast_cleanup_scope(&self, debug_loc: NodeInfo) { + fn push_ast_cleanup_scope(&self, debug_loc: NodeIdAndSpan) { debug!("push_ast_cleanup_scope({})", self.ccx.tcx().map.node_to_string(debug_loc.id)); @@ -139,7 +139,7 @@ fn push_ast_cleanup_scope(&self, debug_loc: NodeInfo) { } self.push_scope(CleanupScope::new(AstScopeKind(debug_loc.id), - Some(debug_loc))); + debug_loc.debug_loc())); } fn push_loop_cleanup_scope(&self, @@ -168,19 +168,20 @@ fn push_custom_cleanup_scope(&self) -> CustomScopeIndex { .borrow() .last() .map(|opt_scope| opt_scope.debug_loc) - .unwrap_or(None); + .unwrap_or(DebugLoc::None); self.push_scope(CleanupScope::new(CustomScopeKind, debug_loc)); CustomScopeIndex { index: index } } fn push_custom_cleanup_scope_with_debug_loc(&self, - debug_loc: NodeInfo) + debug_loc: NodeIdAndSpan) -> CustomScopeIndex { let index = self.scopes_len(); debug!("push_custom_cleanup_scope(): {}", index); - self.push_scope(CleanupScope::new(CustomScopeKind, Some(debug_loc))); + self.push_scope(CleanupScope::new(CustomScopeKind, + debug_loc.debug_loc())); CustomScopeIndex { index: index } } @@ -664,7 +665,7 @@ fn trans_cleanups_to_exit_scope(&'blk self, scope.debug_loc); } } - build::Br(bcx_out, prev_llbb); + build::Br(bcx_out, prev_llbb, DebugLoc::None); prev_llbb = bcx_in.llbb; } else { debug!("no suitable cleanups in {}", @@ -766,7 +767,7 @@ fn get_or_create_landing_pad(&'blk self) -> BasicBlockRef { // Generate the cleanup block and branch to it. let cleanup_llbb = self.trans_cleanups_to_exit_scope(UnwindExit); - build::Br(pad_bcx, cleanup_llbb); + build::Br(pad_bcx, cleanup_llbb, DebugLoc::None); return pad_bcx.llbb; } @@ -774,7 +775,7 @@ fn get_or_create_landing_pad(&'blk self) -> BasicBlockRef { impl<'blk, 'tcx> CleanupScope<'blk, 'tcx> { fn new(kind: CleanupScopeKind<'blk, 'tcx>, - debug_loc: Option) + debug_loc: DebugLoc) -> CleanupScope<'blk, 'tcx> { CleanupScope { kind: kind, @@ -896,7 +897,7 @@ fn is_lifetime_end(&self) -> bool { fn trans<'blk>(&self, bcx: Block<'blk, 'tcx>, - debug_loc: Option) + debug_loc: DebugLoc) -> Block<'blk, 'tcx> { let bcx = if self.is_immediate { glue::drop_ty_immediate(bcx, self.val, self.ty, debug_loc) @@ -937,9 +938,9 @@ fn is_lifetime_end(&self) -> bool { fn trans<'blk>(&self, bcx: Block<'blk, 'tcx>, - debug_loc: Option) + debug_loc: DebugLoc) -> Block<'blk, 'tcx> { - apply_debug_loc(bcx.fcx, debug_loc); + debug_loc.apply(bcx.fcx); match self.heap { HeapExchange => { @@ -972,9 +973,9 @@ fn is_lifetime_end(&self) -> bool { fn trans<'blk>(&self, bcx: Block<'blk, 'tcx>, - debug_loc: Option) + debug_loc: DebugLoc) -> Block<'blk, 'tcx> { - apply_debug_loc(bcx.fcx, debug_loc); + debug_loc.apply(bcx.fcx); match self.heap { HeapExchange => { @@ -1004,9 +1005,9 @@ fn is_lifetime_end(&self) -> bool { fn trans<'blk>(&self, bcx: Block<'blk, 'tcx>, - debug_loc: Option) + debug_loc: DebugLoc) -> Block<'blk, 'tcx> { - apply_debug_loc(bcx.fcx, debug_loc); + debug_loc.apply(bcx.fcx); base::call_lifetime_end(bcx, self.ptr); bcx } @@ -1041,33 +1042,22 @@ fn cleanup_is_suitable_for(c: &Cleanup, !label.is_unwind() || c.clean_on_unwind() } -fn apply_debug_loc(fcx: &FunctionContext, debug_loc: Option) { - match debug_loc { - Some(ref src_loc) => { - debuginfo::set_source_location(fcx, src_loc.id, src_loc.span); - } - None => { - debuginfo::clear_source_location(fcx); - } - } -} - /////////////////////////////////////////////////////////////////////////// // These traits just exist to put the methods into this file. pub trait CleanupMethods<'blk, 'tcx> { - fn push_ast_cleanup_scope(&self, id: NodeInfo); + fn push_ast_cleanup_scope(&self, id: NodeIdAndSpan); fn push_loop_cleanup_scope(&self, id: ast::NodeId, exits: [Block<'blk, 'tcx>; EXIT_MAX]); fn push_custom_cleanup_scope(&self) -> CustomScopeIndex; fn push_custom_cleanup_scope_with_debug_loc(&self, - debug_loc: NodeInfo) + debug_loc: NodeIdAndSpan) -> CustomScopeIndex; fn pop_and_trans_ast_cleanup_scope(&self, - bcx: Block<'blk, 'tcx>, - cleanup_scope: ast::NodeId) - -> Block<'blk, 'tcx>; + bcx: Block<'blk, 'tcx>, + cleanup_scope: ast::NodeId) + -> Block<'blk, 'tcx>; fn pop_loop_cleanup_scope(&self, cleanup_scope: ast::NodeId); fn pop_custom_cleanup_scope(&self, diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index 8989dfd4932..7a6c0c50dd1 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -10,270 +10,26 @@ pub use self::ClosureKind::*; -use back::abi; use back::link::mangle_internal_name_by_path_and_seq; -use llvm::ValueRef; use middle::mem_categorization::Typer; use trans::adt; use trans::base::*; use trans::build::*; use trans::cleanup::{CleanupMethods, ScopeId}; use trans::common::*; -use trans::datum::{Datum, Lvalue, rvalue_scratch_datum}; +use trans::datum::{Datum, rvalue_scratch_datum}; use trans::datum::{Rvalue, ByValue}; use trans::debuginfo; use trans::expr; use trans::monomorphize::{self, MonoId}; use trans::type_of::*; -use trans::type_::Type; -use middle::ty::{self, Ty, UnboxedClosureTyper}; +use middle::ty::{self, UnboxedClosureTyper}; use middle::subst::{Substs}; use session::config::FullDebugInfo; -use util::ppaux::ty_to_string; use syntax::ast; use syntax::ast_util; -// ___Good to know (tm)__________________________________________________ -// -// The layout of a closure environment in memory is -// roughly as follows: -// -// struct rust_opaque_box { // see rust_internal.h -// unsigned ref_count; // obsolete (part of @T's header) -// fn(void*) *drop_glue; // destructor (for proc) -// rust_opaque_box *prev; // obsolete (part of @T's header) -// rust_opaque_box *next; // obsolete (part of @T's header) -// struct closure_data { -// upvar1_t upvar1; -// ... -// upvarN_t upvarN; -// } -// }; -// -// Note that the closure is itself a rust_opaque_box. This is true -// even for ~fn and ||, because we wish to keep binary compatibility -// between all kinds of closures. The allocation strategy for this -// closure depends on the closure type. For a sendfn, the closure -// (and the referenced type descriptors) will be allocated in the -// exchange heap. For a fn, the closure is allocated in the task heap -// and is reference counted. For a block, the closure is allocated on -// the stack. -// -// ## Opaque closures and the embedded type descriptor ## -// -// One interesting part of closures is that they encapsulate the data -// that they close over. So when I have a ptr to a closure, I do not -// know how many type descriptors it contains nor what upvars are -// captured within. That means I do not know precisely how big it is -// nor where its fields are located. This is called an "opaque -// closure". -// -// Typically an opaque closure suffices because we only manipulate it -// by ptr. The routine Type::at_box().ptr_to() returns an appropriate -// type for such an opaque closure; it allows access to the box fields, -// but not the closure_data itself. -// -// But sometimes, such as when cloning or freeing a closure, we need -// to know the full information. That is where the type descriptor -// that defines the closure comes in handy. We can use its take and -// drop glue functions to allocate/free data as needed. -// -// ## Subtleties concerning alignment ## -// -// It is important that we be able to locate the closure data *without -// knowing the kind of data that is being bound*. This can be tricky -// because the alignment requirements of the bound data affects the -// alignment requires of the closure_data struct as a whole. However, -// right now this is a non-issue in any case, because the size of the -// rust_opaque_box header is always a multiple of 16-bytes, which is -// the maximum alignment requirement we ever have to worry about. -// -// The only reason alignment matters is that, in order to learn what data -// is bound, we would normally first load the type descriptors: but their -// location is ultimately depend on their content! There is, however, a -// workaround. We can load the tydesc from the rust_opaque_box, which -// describes the closure_data struct and has self-contained derived type -// descriptors, and read the alignment from there. It's just annoying to -// do. Hopefully should this ever become an issue we'll have monomorphized -// and type descriptors will all be a bad dream. -// -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -#[derive(Copy)] -pub struct EnvValue<'tcx> { - action: ast::CaptureClause, - datum: Datum<'tcx, Lvalue> -} - -impl<'tcx> EnvValue<'tcx> { - pub fn to_string<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> String { - format!("{:?}({})", self.action, self.datum.to_string(ccx)) - } -} - -// Given a closure ty, emits a corresponding tuple ty -pub fn mk_closure_tys<'tcx>(tcx: &ty::ctxt<'tcx>, - bound_values: &[EnvValue<'tcx>]) - -> Ty<'tcx> { - // determine the types of the values in the env. Note that this - // is the actual types that will be stored in the map, not the - // logical types as the user sees them, so by-ref upvars must be - // converted to ptrs. - let bound_tys = bound_values.iter().map(|bv| { - match bv.action { - ast::CaptureByValue => bv.datum.ty, - ast::CaptureByRef => ty::mk_mut_ptr(tcx, bv.datum.ty) - } - }).collect(); - let cdata_ty = ty::mk_tup(tcx, bound_tys); - debug!("cdata_ty={}", ty_to_string(tcx, cdata_ty)); - return cdata_ty; -} - -fn tuplify_box_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> Ty<'tcx> { - let ptr = ty::mk_imm_ptr(tcx, tcx.types.i8); - ty::mk_tup(tcx, vec!(tcx.types.uint, ty::mk_nil_ptr(tcx), ptr, ptr, t)) -} - -pub struct ClosureResult<'blk, 'tcx: 'blk> { - llbox: ValueRef, // llvalue of ptr to closure - cdata_ty: Ty<'tcx>, // type of the closure data - bcx: Block<'blk, 'tcx> // final bcx -} - -// Given a block context and a list of tydescs and values to bind -// construct a closure out of them. If copying is true, it is a -// heap allocated closure that copies the upvars into environment. -// Otherwise, it is stack allocated and copies pointers to the upvars. -pub fn store_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - bound_values: Vec>) - -> ClosureResult<'blk, 'tcx> { - let _icx = push_ctxt("closure::store_environment"); - let ccx = bcx.ccx(); - let tcx = ccx.tcx(); - - // compute the type of the closure - let cdata_ty = mk_closure_tys(tcx, &bound_values[]); - - // cbox_ty has the form of a tuple: (a, b, c) we want a ptr to a - // tuple. This could be a ptr in uniq or a box or on stack, - // whatever. - let cbox_ty = tuplify_box_ty(tcx, cdata_ty); - let cboxptr_ty = ty::mk_ptr(tcx, ty::mt {ty:cbox_ty, mutbl:ast::MutImmutable}); - let llboxptr_ty = type_of(ccx, cboxptr_ty); - - // If there are no bound values, no point in allocating anything. - if bound_values.is_empty() { - return ClosureResult {llbox: C_null(llboxptr_ty), - cdata_ty: cdata_ty, - bcx: bcx}; - } - - // allocate closure in the heap - let llbox = alloc_ty(bcx, cbox_ty, "__closure"); - - let llbox = PointerCast(bcx, llbox, llboxptr_ty); - debug!("tuplify_box_ty = {}", ty_to_string(tcx, cbox_ty)); - - // Copy expr values into boxed bindings. - let mut bcx = bcx; - for (i, bv) in bound_values.into_iter().enumerate() { - debug!("Copy {} into closure", bv.to_string(ccx)); - - if ccx.sess().asm_comments() { - add_comment(bcx, &format!("Copy {} into closure", - bv.to_string(ccx))[]); - } - - let bound_data = GEPi(bcx, llbox, &[0u, abi::BOX_FIELD_BODY, i]); - - match bv.action { - ast::CaptureByValue => { - bcx = bv.datum.store_to(bcx, bound_data); - } - ast::CaptureByRef => { - Store(bcx, bv.datum.to_llref(), bound_data); - } - } - } - - ClosureResult { llbox: llbox, cdata_ty: cdata_ty, bcx: bcx } -} - -// Given a context and a list of upvars, build a closure. This just -// collects the upvars and packages them up for store_environment. -fn build_closure<'blk, 'tcx>(bcx0: Block<'blk, 'tcx>, - freevar_mode: ast::CaptureClause, - freevars: &Vec) - -> ClosureResult<'blk, 'tcx> { - let _icx = push_ctxt("closure::build_closure"); - - // If we need to, package up the iterator body to call - let bcx = bcx0; - - // Package up the captured upvars - let mut env_vals = Vec::new(); - for freevar in freevars.iter() { - let datum = expr::trans_local_var(bcx, freevar.def); - env_vals.push(EnvValue {action: freevar_mode, datum: datum}); - } - - store_environment(bcx, env_vals) -} - -// Given an enclosing block context, a new function context, a closure type, -// and a list of upvars, generate code to load and populate the environment -// with the upvars and type descriptors. -fn load_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - cdata_ty: Ty<'tcx>, - freevars: &[ty::Freevar], - store: ty::TraitStore) - -> Block<'blk, 'tcx> { - let _icx = push_ctxt("closure::load_environment"); - - // Load a pointer to the closure data, skipping over the box header: - let llcdata = at_box_body(bcx, cdata_ty, bcx.fcx.llenv.unwrap()); - - // Store the pointer to closure data in an alloca for debug info because that's what the - // llvm.dbg.declare intrinsic expects - let env_pointer_alloca = if bcx.sess().opts.debuginfo == FullDebugInfo { - let alloc = alloc_ty(bcx, ty::mk_mut_ptr(bcx.tcx(), cdata_ty), "__debuginfo_env_ptr"); - Store(bcx, llcdata, alloc); - Some(alloc) - } else { - None - }; - - // Populate the upvars from the environment - let mut i = 0u; - for freevar in freevars.iter() { - let mut upvarptr = GEPi(bcx, llcdata, &[0u, i]); - let captured_by_ref = match store { - ty::RegionTraitStore(..) => { - upvarptr = Load(bcx, upvarptr); - true - } - ty::UniqTraitStore => false - }; - let def_id = freevar.def.def_id(); - - bcx.fcx.llupvars.borrow_mut().insert(def_id.node, upvarptr); - if let Some(env_pointer_alloca) = env_pointer_alloca { - debuginfo::create_captured_var_metadata( - bcx, - def_id.node, - env_pointer_alloca, - i, - captured_by_ref, - freevar.span); - } - - i += 1u; - } - - bcx -} fn load_unboxed_closure_environment<'blk, 'tcx>( bcx: Block<'blk, 'tcx>, @@ -281,7 +37,7 @@ fn load_unboxed_closure_environment<'blk, 'tcx>( freevar_mode: ast::CaptureClause, freevars: &[ty::Freevar]) -> Block<'blk, 'tcx> { - let _icx = push_ctxt("closure::load_environment"); + let _icx = push_ctxt("closure::load_unboxed_closure_environment"); // Special case for small by-value selfs. let closure_id = ast_util::local_def(bcx.fcx.id); @@ -341,17 +97,9 @@ fn load_unboxed_closure_environment<'blk, 'tcx>( bcx } -fn fill_fn_pair(bcx: Block, pair: ValueRef, llfn: ValueRef, llenvptr: ValueRef) { - Store(bcx, llfn, GEPi(bcx, pair, &[0u, abi::FAT_PTR_ADDR])); - let llenvptr = PointerCast(bcx, llenvptr, Type::i8p(bcx.ccx())); - Store(bcx, llenvptr, GEPi(bcx, pair, &[0u, abi::FAT_PTR_EXTRA])); -} - #[derive(PartialEq)] pub enum ClosureKind<'tcx> { NotClosure, - // See load_environment. - BoxedClosure(Ty<'tcx>, ty::TraitStore), // See load_unboxed_closure_environment. UnboxedClosure(ast::CaptureClause) } @@ -379,9 +127,6 @@ pub fn load<'blk>(self, bcx: Block<'blk, 'tcx>, arg_scope: ScopeId) match self.kind { NotClosure => bcx, - BoxedClosure(cdata_ty, store) => { - load_environment(bcx, cdata_ty, self.freevars, store) - } UnboxedClosure(freevar_mode) => { load_unboxed_closure_environment(bcx, arg_scope, freevar_mode, self.freevars) } @@ -389,67 +134,6 @@ pub fn load<'blk>(self, bcx: Block<'blk, 'tcx>, arg_scope: ScopeId) } } -/// Translates the body of a closure expression. -/// -/// - `store` -/// - `decl` -/// - `body` -/// - `id`: The id of the closure expression. -/// - `cap_clause`: information about captured variables, if any. -/// - `dest`: where to write the closure value, which must be a -/// (fn ptr, env) pair -pub fn trans_expr_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - store: ty::TraitStore, - decl: &ast::FnDecl, - body: &ast::Block, - id: ast::NodeId, - dest: expr::Dest) - -> Block<'blk, 'tcx> { - let _icx = push_ctxt("closure::trans_expr_fn"); - - let dest_addr = match dest { - expr::SaveIn(p) => p, - expr::Ignore => { - return bcx; // closure construction is non-side-effecting - } - }; - - let ccx = bcx.ccx(); - let tcx = bcx.tcx(); - let fty = node_id_type(bcx, id); - let s = tcx.map.with_path(id, |path| { - mangle_internal_name_by_path_and_seq(path, "closure") - }); - let llfn = decl_internal_rust_fn(ccx, fty, &s[]); - - // set an inline hint for all closures - set_inline_hint(llfn); - - let freevar_mode = tcx.capture_mode(id); - let freevars: Vec = - ty::with_freevars(tcx, id, |fv| fv.iter().map(|&fv| fv).collect()); - - let ClosureResult { - llbox, - cdata_ty, - bcx - } = build_closure(bcx, freevar_mode, &freevars); - - trans_closure(ccx, - decl, - body, - llfn, - bcx.fcx.param_substs, - id, - &[], - ty::erase_late_bound_regions(ccx.tcx(), &ty::ty_fn_ret(fty)), - ty::ty_fn_abi(fty), - ClosureEnv::new(&freevars[], - BoxedClosure(cdata_ty, store))); - fill_fn_pair(bcx, dest_addr, llfn, llbox); - bcx -} - /// Returns the LLVM function declaration for an unboxed closure, creating it /// if necessary. If the ID does not correspond to a closure ID, returns None. pub fn get_or_create_declaration_if_unboxed_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 312fd33ef1f..3bc851c5595 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -30,7 +30,7 @@ use trans::cleanup; use trans::consts; use trans::datum; -use trans::debuginfo; +use trans::debuginfo::{self, DebugLoc}; use trans::machine; use trans::monomorphize; use trans::type_::Type; @@ -275,7 +275,7 @@ pub fn return_type_is_void(ccx: &CrateContext, ty: Ty) -> bool { /// Generates a unique symbol based off the name given. This is used to create /// unique symbols for things like closures. pub fn gensym_name(name: &str) -> PathElem { - let num = token::gensym(name).uint(); + let num = token::gensym(name).usize(); // use one colon which will get translated to a period by the mangler, and // we're guaranteed that `num` is globally unique for this crate. PathName(token::gensym(&format!("{}:{}", name, num)[])) @@ -317,13 +317,13 @@ pub struct tydesc_info<'tcx> { */ #[derive(Copy)] -pub struct NodeInfo { +pub struct NodeIdAndSpan { pub id: ast::NodeId, pub span: Span, } -pub fn expr_info(expr: &ast::Expr) -> NodeInfo { - NodeInfo { id: expr.id, span: expr.span } +pub fn expr_info(expr: &ast::Expr) -> NodeIdAndSpan { + NodeIdAndSpan { id: expr.id, span: expr.span } } pub struct BuilderRef_res { @@ -517,7 +517,7 @@ pub fn join_blocks(&'a self, let mut reachable = false; for bcx in in_cxs.iter() { if !bcx.unreachable.get() { - build::Br(*bcx, out.llbb); + build::Br(*bcx, out.llbb, DebugLoc::None); reachable = true; } } @@ -848,7 +848,7 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va !null_terminated as Bool); let gsym = token::gensym("str"); - let buf = CString::from_vec(format!("str{}", gsym.uint()).into_bytes()); + let buf = CString::from_vec(format!("str{}", gsym.usize()).into_bytes()); let g = llvm::LLVMAddGlobal(cx.llmod(), val_ty(sc).to_ref(), buf.as_ptr()); llvm::LLVMSetInitializer(g, sc); llvm::LLVMSetGlobalConstant(g, True); @@ -873,7 +873,7 @@ pub fn C_binary_slice(cx: &CrateContext, data: &[u8]) -> ValueRef { let lldata = C_bytes(cx, data); let gsym = token::gensym("binary"); - let name = format!("binary{}", gsym.uint()); + let name = format!("binary{}", gsym.usize()); let name = CString::from_vec(name.into_bytes()); let g = llvm::LLVMAddGlobal(cx.llmod(), val_ty(lldata).to_ref(), name.as_ptr()); diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs index 5dc939dc202..bea8a759971 100644 --- a/src/librustc_trans/trans/controlflow.rs +++ b/src/librustc_trans/trans/controlflow.rs @@ -22,6 +22,7 @@ use trans::consts; use trans::datum; use trans::debuginfo; +use trans::debuginfo::{DebugLoc, ToDebugLoc}; use trans::expr; use trans::meth; use trans::type_::Type; @@ -188,6 +189,8 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let then_bcx_out = trans_block(then_bcx_in, &*thn, dest); trans::debuginfo::clear_source_location(bcx.fcx); + let cond_source_loc = cond.debug_loc(); + let next_bcx; match els { Some(elexpr) => { @@ -195,13 +198,13 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let else_bcx_out = expr::trans_into(else_bcx_in, &*elexpr, dest); next_bcx = bcx.fcx.join_blocks(if_id, &[then_bcx_out, else_bcx_out]); - CondBr(bcx, cond_val, then_bcx_in.llbb, else_bcx_in.llbb); + CondBr(bcx, cond_val, then_bcx_in.llbb, else_bcx_in.llbb, cond_source_loc); } None => { next_bcx = bcx.fcx.new_id_block("next-block", if_id); - Br(then_bcx_out, next_bcx.llbb); - CondBr(bcx, cond_val, then_bcx_in.llbb, next_bcx.llbb); + Br(then_bcx_out, next_bcx.llbb, DebugLoc::None); + CondBr(bcx, cond_val, then_bcx_in.llbb, next_bcx.llbb, cond_source_loc); } } @@ -213,7 +216,7 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } pub fn trans_while<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - loop_id: ast::NodeId, + loop_expr: &ast::Expr, cond: &ast::Expr, body: &ast::Block) -> Block<'blk, 'tcx> { @@ -231,33 +234,34 @@ pub fn trans_while<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // | body_bcx_out --+ // next_bcx_in - let next_bcx_in = fcx.new_id_block("while_exit", loop_id); + let next_bcx_in = fcx.new_id_block("while_exit", loop_expr.id); let cond_bcx_in = fcx.new_id_block("while_cond", cond.id); let body_bcx_in = fcx.new_id_block("while_body", body.id); - fcx.push_loop_cleanup_scope(loop_id, [next_bcx_in, cond_bcx_in]); + fcx.push_loop_cleanup_scope(loop_expr.id, [next_bcx_in, cond_bcx_in]); - Br(bcx, cond_bcx_in.llbb); + Br(bcx, cond_bcx_in.llbb, loop_expr.debug_loc()); // compile the block where we will handle loop cleanups - let cleanup_llbb = fcx.normal_exit_block(loop_id, cleanup::EXIT_BREAK); + let cleanup_llbb = fcx.normal_exit_block(loop_expr.id, cleanup::EXIT_BREAK); // compile the condition let Result {bcx: cond_bcx_out, val: cond_val} = expr::trans(cond_bcx_in, cond).to_llbool(); - CondBr(cond_bcx_out, cond_val, body_bcx_in.llbb, cleanup_llbb); + + CondBr(cond_bcx_out, cond_val, body_bcx_in.llbb, cleanup_llbb, cond.debug_loc()); // loop body: let body_bcx_out = trans_block(body_bcx_in, body, expr::Ignore); - Br(body_bcx_out, cond_bcx_in.llbb); + Br(body_bcx_out, cond_bcx_in.llbb, DebugLoc::None); - fcx.pop_loop_cleanup_scope(loop_id); + fcx.pop_loop_cleanup_scope(loop_expr.id); return next_bcx_in; } /// Translates a `for` loop. pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, - loop_info: NodeInfo, + loop_info: NodeIdAndSpan, pat: &ast::Pat, head: &ast::Expr, body: &ast::Block) @@ -292,7 +296,7 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let body_bcx_in = bcx.fcx.new_id_block("for_body", body.id); bcx.fcx.push_loop_cleanup_scope(loop_info.id, [next_bcx_in, loopback_bcx_in]); - Br(bcx, loopback_bcx_in.llbb); + Br(bcx, loopback_bcx_in.llbb, DebugLoc::None); let cleanup_llbb = bcx.fcx.normal_exit_block(loop_info.id, cleanup::EXIT_BREAK); @@ -347,7 +351,7 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, None); let i1_type = Type::i1(loopback_bcx_out.ccx()); let llcondition = Trunc(loopback_bcx_out, lldiscriminant, i1_type); - CondBr(loopback_bcx_out, llcondition, body_bcx_in.llbb, cleanup_llbb); + CondBr(loopback_bcx_out, llcondition, body_bcx_in.llbb, cleanup_llbb, DebugLoc::None); // Now we're in the body. Unpack the `Option` value into the programmer- // supplied pattern. @@ -377,7 +381,7 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, body_bcx_out.fcx .pop_and_trans_custom_cleanup_scope(body_bcx_out, option_cleanup_scope); - Br(body_bcx_out, loopback_bcx_in.llbb); + Br(body_bcx_out, loopback_bcx_in.llbb, DebugLoc::None); // Codegen cleanups and leave. next_bcx_in.fcx.pop_loop_cleanup_scope(loop_info.id); @@ -385,7 +389,7 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } pub fn trans_loop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - loop_id: ast::NodeId, + loop_expr: &ast::Expr, body: &ast::Block) -> Block<'blk, 'tcx> { let _icx = push_ctxt("trans_loop"); @@ -402,22 +406,22 @@ pub fn trans_loop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // Links between body_bcx_in and next_bcx are created by // break statements. - let next_bcx_in = bcx.fcx.new_id_block("loop_exit", loop_id); + let next_bcx_in = bcx.fcx.new_id_block("loop_exit", loop_expr.id); let body_bcx_in = bcx.fcx.new_id_block("loop_body", body.id); - fcx.push_loop_cleanup_scope(loop_id, [next_bcx_in, body_bcx_in]); + fcx.push_loop_cleanup_scope(loop_expr.id, [next_bcx_in, body_bcx_in]); - Br(bcx, body_bcx_in.llbb); + Br(bcx, body_bcx_in.llbb, loop_expr.debug_loc()); let body_bcx_out = trans_block(body_bcx_in, body, expr::Ignore); - Br(body_bcx_out, body_bcx_in.llbb); + Br(body_bcx_out, body_bcx_in.llbb, DebugLoc::None); - fcx.pop_loop_cleanup_scope(loop_id); + fcx.pop_loop_cleanup_scope(loop_expr.id); return next_bcx_in; } pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - expr_id: ast::NodeId, + expr: &ast::Expr, opt_label: Option, exit: uint) -> Block<'blk, 'tcx> { @@ -432,7 +436,7 @@ pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let loop_id = match opt_label { None => fcx.top_loop_scope(), Some(_) => { - match bcx.tcx().def_map.borrow().get(&expr_id) { + match bcx.tcx().def_map.borrow().get(&expr.id) { Some(&def::DefLabel(loop_id)) => loop_id, ref r => { bcx.tcx().sess.bug(&format!("{:?} in def-map for label", @@ -444,39 +448,40 @@ pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // Generate appropriate cleanup code and branch let cleanup_llbb = fcx.normal_exit_block(loop_id, exit); - Br(bcx, cleanup_llbb); + Br(bcx, cleanup_llbb, expr.debug_loc()); Unreachable(bcx); // anything afterwards should be ignored return bcx; } pub fn trans_break<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - expr_id: ast::NodeId, + expr: &ast::Expr, label_opt: Option) -> Block<'blk, 'tcx> { - return trans_break_cont(bcx, expr_id, label_opt, cleanup::EXIT_BREAK); + return trans_break_cont(bcx, expr, label_opt, cleanup::EXIT_BREAK); } pub fn trans_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - expr_id: ast::NodeId, + expr: &ast::Expr, label_opt: Option) -> Block<'blk, 'tcx> { - return trans_break_cont(bcx, expr_id, label_opt, cleanup::EXIT_LOOP); + return trans_break_cont(bcx, expr, label_opt, cleanup::EXIT_LOOP); } pub fn trans_ret<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - e: Option<&ast::Expr>) + return_expr: &ast::Expr, + retval_expr: Option<&ast::Expr>) -> Block<'blk, 'tcx> { let _icx = push_ctxt("trans_ret"); let fcx = bcx.fcx; let mut bcx = bcx; - let dest = match (fcx.llretslotptr.get(), e) { - (Some(_), Some(e)) => { - let ret_ty = expr_ty(bcx, &*e); + let dest = match (fcx.llretslotptr.get(), retval_expr) { + (Some(_), Some(retval_expr)) => { + let ret_ty = expr_ty(bcx, &*retval_expr); expr::SaveIn(fcx.get_ret_slot(bcx, ty::FnConverging(ret_ty), "ret_slot")) } _ => expr::Ignore, }; - if let Some(x) = e { + if let Some(x) = retval_expr { bcx = expr::trans_into(bcx, &*x, dest); match dest { expr::SaveIn(slot) if fcx.needs_ret_allocas => { @@ -486,7 +491,7 @@ pub fn trans_ret<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } } let cleanup_llbb = fcx.return_exit_block(); - Br(bcx, cleanup_llbb); + Br(bcx, cleanup_llbb, return_expr.debug_loc()); Unreachable(bcx); return bcx; } diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index 8b52732f4ee..cba12babb9b 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -481,7 +481,7 @@ pub fn get_vec_base_and_len(&self, bcx: Block) -> (ValueRef, ValueRef) { } /// Generic methods applicable to any sort of datum. -impl<'tcx, K: KindOps + fmt::Show> Datum<'tcx, K> { +impl<'tcx, K: KindOps + fmt::Debug> Datum<'tcx, K> { pub fn new(val: ValueRef, ty: Ty<'tcx>, kind: K) -> Datum<'tcx, K> { Datum { val: val, ty: ty, kind: kind } } @@ -591,7 +591,7 @@ pub fn new(bcx: Block<'blk, 'tcx>, datum: Datum<'tcx, K>) } } -impl<'blk, 'tcx, K: KindOps + fmt::Show> DatumBlock<'blk, 'tcx, K> { +impl<'blk, 'tcx, K: KindOps + fmt::Debug> DatumBlock<'blk, 'tcx, K> { pub fn to_expr_datumblock(self) -> DatumBlock<'blk, 'tcx, Expr> { DatumBlock::new(self.bcx, self.datum.to_expr_datum()) } diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 2f01f0328e2..9df1b236fe8 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -188,7 +188,7 @@ use self::MemberDescriptionFactory::*; use self::RecursiveTypeDescription::*; use self::EnumDiscriminantInfo::*; -use self::DebugLocation::*; +use self::InternalDebugLocation::*; use llvm; use llvm::{ModuleRef, ContextRef, ValueRef}; @@ -196,7 +196,8 @@ use metadata::csearch; use middle::subst::{self, Substs}; use trans::{self, adt, machine, type_of}; -use trans::common::*; +use trans::common::{self, NodeIdAndSpan, CrateContext, FunctionContext, Block, + C_bytes, C_i32, C_i64, NormalizingUnboxedClosureTyper}; use trans::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef}; use trans::monomorphize; use trans::type_::Type; @@ -551,28 +552,14 @@ fn get_unique_type_id_of_closure_type<'a>(&mut self, closure_ty: ty::ClosureTy<'tcx>, unique_type_id: &mut String) { let ty::ClosureTy { unsafety, - onceness, - store, - ref bounds, ref sig, abi: _ } = closure_ty; + if unsafety == ast::Unsafety::Unsafe { unique_type_id.push_str("unsafe "); } - if onceness == ast::Once { - unique_type_id.push_str("once "); - } - - match store { - ty::UniqTraitStore => unique_type_id.push_str("~|"), - ty::RegionTraitStore(_, ast::MutMutable) => { - unique_type_id.push_str("&mut|") - } - ty::RegionTraitStore(_, ast::MutImmutable) => { - unique_type_id.push_str("&|") - } - }; + unique_type_id.push_str("|"); let sig = ty::erase_late_bound_regions(cx.tcx(), sig); @@ -601,18 +588,6 @@ fn get_unique_type_id_of_closure_type<'a>(&mut self, unique_type_id.push_str("!"); } } - - unique_type_id.push(':'); - - for bound in bounds.builtin_bounds.iter() { - match bound { - ty::BoundSend => unique_type_id.push_str("Send"), - ty::BoundSized => unique_type_id.push_str("Sized"), - ty::BoundCopy => unique_type_id.push_str("Copy"), - ty::BoundSync => unique_type_id.push_str("Sync"), - }; - unique_type_id.push('+'); - } } // Get the UniqueTypeId for an enum variant. Enum variants are not really @@ -650,7 +625,7 @@ macro_rules! return_if_metadata_created_in_meantime { pub struct CrateDebugContext<'tcx> { llcontext: ContextRef, builder: DIBuilderRef, - current_debug_location: Cell, + current_debug_location: Cell, created_files: RefCell>, created_enum_disr_types: RefCell>, @@ -940,13 +915,14 @@ pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } }; - let variable_type = node_id_type(bcx, node_id); + let variable_type = common::node_id_type(bcx, node_id); let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata; // env_pointer is the alloca containing the pointer to the environment, // so it's type is **EnvironmentType. In order to find out the type of // the environment we have to "dereference" two times. - let llvm_env_data_type = val_ty(env_pointer).element_type().element_type(); + let llvm_env_data_type = common::val_ty(env_pointer).element_type() + .element_type(); let byte_offset_of_var_in_env = machine::llelement_offset(cx, llvm_env_data_type, env_index); @@ -1123,7 +1099,7 @@ pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, node_id: ast::NodeId, node_span: Span, is_block: bool) - -> NodeInfo { + -> NodeIdAndSpan { // A debug location needs two things: // (1) A span (of which only the beginning will actually be used) // (2) An AST node-id which will be used to look up the lexical scope @@ -1163,7 +1139,7 @@ pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, if let Some(code_snippet) = code_snippet { let bytes = code_snippet.as_bytes(); - if bytes.len() > 0 && &bytes[(bytes.len()-1)..] == b"}" { + if bytes.len() > 0 && &bytes[bytes.len()-1..] == b"}" { cleanup_span = Span { lo: node_span.hi - codemap::BytePos(1), hi: node_span.hi, @@ -1173,12 +1149,56 @@ pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } } - NodeInfo { + NodeIdAndSpan { id: node_id, span: cleanup_span } } +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum DebugLoc { + At(ast::NodeId, Span), + None +} + +impl DebugLoc { + pub fn apply(&self, fcx: &FunctionContext) { + match *self { + DebugLoc::At(node_id, span) => { + set_source_location(fcx, node_id, span); + } + DebugLoc::None => { + clear_source_location(fcx); + } + } + } +} + +pub trait ToDebugLoc { + fn debug_loc(&self) -> DebugLoc; +} + +impl ToDebugLoc for ast::Expr { + fn debug_loc(&self) -> DebugLoc { + DebugLoc::At(self.id, self.span) + } +} + +impl ToDebugLoc for NodeIdAndSpan { + fn debug_loc(&self) -> DebugLoc { + DebugLoc::At(self.id, self.span) + } +} + +impl ToDebugLoc for Option { + fn debug_loc(&self) -> DebugLoc { + match *self { + Some(NodeIdAndSpan { id, span }) => DebugLoc::At(id, span), + None => DebugLoc::None + } + } +} + /// Sets the current debug location at the beginning of the span. /// /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). The node_id @@ -1202,9 +1222,9 @@ pub fn set_source_location(fcx: &FunctionContext, let loc = span_start(cx, span); let scope = scope_metadata(fcx, node_id, span); - set_debug_location(cx, DebugLocation::new(scope, - loc.line, - loc.col.to_uint())); + set_debug_location(cx, InternalDebugLocation::new(scope, + loc.line, + loc.col.to_usize())); } else { set_debug_location(cx, UnknownLocation); } @@ -1615,8 +1635,8 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { let prefix: &[u8] = &[dotdot[0], ::std::path::SEP_BYTE]; let mut path_bytes = p.as_vec().to_vec(); - if path_bytes.slice_to(2) != prefix && - path_bytes.slice_to(2) != dotdot { + if &path_bytes[..2] != prefix && + &path_bytes[..2] != dotdot { path_bytes.insert(0, prefix[0]); path_bytes.insert(1, prefix[1]); } @@ -1714,9 +1734,9 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ) }; - set_debug_location(cx, DebugLocation::new(scope_metadata, - loc.line, - loc.col.to_uint())); + set_debug_location(cx, InternalDebugLocation::new(scope_metadata, + loc.line, + loc.col.to_usize())); unsafe { let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd( DIB(cx), @@ -1752,7 +1772,7 @@ fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile { let work_dir = cx.sess().working_dir.as_str().unwrap(); let file_name = if full_path.starts_with(work_dir) { - &full_path[(work_dir.len() + 1u)..full_path.len()] + &full_path[work_dir.len() + 1u..full_path.len()] } else { full_path }; @@ -3095,13 +3115,13 @@ fn new(metadata: DIType, already_stored_in_typemap: bool) -> MetadataCreationRes } #[derive(Copy, PartialEq)] -enum DebugLocation { +enum InternalDebugLocation { KnownLocation { scope: DIScope, line: uint, col: uint }, UnknownLocation } -impl DebugLocation { - fn new(scope: DIScope, line: uint, col: uint) -> DebugLocation { +impl InternalDebugLocation { + fn new(scope: DIScope, line: uint, col: uint) -> InternalDebugLocation { KnownLocation { scope: scope, line: line, @@ -3110,7 +3130,7 @@ fn new(scope: DIScope, line: uint, col: uint) -> DebugLocation { } } -fn set_debug_location(cx: &CrateContext, debug_location: DebugLocation) { +fn set_debug_location(cx: &CrateContext, debug_location: InternalDebugLocation) { if debug_location == debug_context(cx).current_debug_location.get() { return; } @@ -3279,7 +3299,7 @@ fn with_new_scope(cx: &CrateContext, parent_scope, file_metadata, loc.line as c_uint, - loc.col.to_uint() as c_uint) + loc.col.to_usize() as c_uint) }; scope_stack.push(ScopeStackEntry { scope_metadata: scope_metadata, @@ -3401,7 +3421,7 @@ fn walk_pattern(cx: &CrateContext, parent_scope, file_metadata, loc.line as c_uint, - loc.col.to_uint() as c_uint) + loc.col.to_usize() as c_uint) }; scope_stack.push(ScopeStackEntry { @@ -4122,4 +4142,3 @@ fn needs_gdb_debug_scripts_section(ccx: &CrateContext) -> bool { !ccx.sess().target.target.options.is_like_windows && ccx.sess().opts.debuginfo != NoDebugInfo } - diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 11d1c7e6796..4ebaf91d111 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -46,7 +46,7 @@ use trans::cleanup::{self, CleanupMethods}; use trans::common::*; use trans::datum::*; -use trans::debuginfo; +use trans::debuginfo::{self, DebugLoc, ToDebugLoc}; use trans::glue; use trans::machine; use trans::meth; @@ -65,7 +65,6 @@ use trans::type_::Type; use syntax::{ast, ast_util, codemap}; -use syntax::print::pprust::{expr_to_string}; use syntax::ptr::P; use syntax::parse::token; use std::rc::Rc; @@ -779,7 +778,8 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let expected = Call(bcx, expect, &[bounds_check, C_bool(ccx, false)], - None); + None, + index_expr.debug_loc()); bcx = with_cond(bcx, expected, |bcx| { controlflow::trans_fail_bounds_check(bcx, index_expr.span, @@ -890,10 +890,10 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, trans_into(bcx, &**e, Ignore) } ast::ExprBreak(label_opt) => { - controlflow::trans_break(bcx, expr.id, label_opt) + controlflow::trans_break(bcx, expr, label_opt) } ast::ExprAgain(label_opt) => { - controlflow::trans_cont(bcx, expr.id, label_opt) + controlflow::trans_cont(bcx, expr, label_opt) } ast::ExprRet(ref ex) => { // Check to see if the return expression itself is reachable. @@ -905,7 +905,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, }; if reachable { - controlflow::trans_ret(bcx, ex.as_ref().map(|e| &**e)) + controlflow::trans_ret(bcx, expr, ex.as_ref().map(|e| &**e)) } else { // If it's not reachable, just translate the inner expression // directly. This avoids having to manage a return slot when @@ -921,7 +921,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } } ast::ExprWhile(ref cond, ref body, _) => { - controlflow::trans_while(bcx, expr.id, &**cond, &**body) + controlflow::trans_while(bcx, expr, &**cond, &**body) } ast::ExprForLoop(ref pat, ref head, ref body, _) => { controlflow::trans_for(bcx, @@ -931,7 +931,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, &**body) } ast::ExprLoop(ref body, _) => { - controlflow::trans_loop(bcx, expr.id, &**body) + controlflow::trans_loop(bcx, expr, &**body) } ast::ExprAssign(ref dst, ref src) => { let src_datum = unpack_datum!(bcx, trans(bcx, &**src)); @@ -960,7 +960,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, bcx = glue::drop_ty(bcx, dst_datum.val, dst_datum.ty, - Some(NodeInfo { id: expr.id, span: expr.span })); + expr.debug_loc()); src_datum.store_to(bcx, dst_datum.val) } else { src_datum.store_to(bcx, dst_datum.val) @@ -1078,7 +1078,7 @@ fn make_field(field_name: &str, expr: P) -> ast::Field { &numbered_fields[], None, dest, - Some(NodeInfo { id: expr.id, span: expr.span })) + expr.debug_loc()) } ast::ExprLit(ref lit) => { match lit.node { @@ -1102,17 +1102,7 @@ fn make_field(field_name: &str, expr: P) -> ast::Field { // closure or an older, legacy style closure. Store this // into a variable to ensure the the RefCell-lock is // released before we recurse. - let is_unboxed_closure = - bcx.tcx().unboxed_closures.borrow().contains_key(&ast_util::local_def(expr.id)); - if is_unboxed_closure { - closure::trans_unboxed_closure(bcx, &**decl, &**body, expr.id, dest) - } else { - let expr_ty = expr_ty(bcx, expr); - let store = ty::ty_closure_store(expr_ty); - debug!("translating block function {} with type {}", - expr_to_string(expr), expr_ty.repr(tcx)); - closure::trans_expr_fn(bcx, store, &**decl, &**body, expr.id, dest) - } + closure::trans_unboxed_closure(bcx, &**decl, &**body, expr.id, dest) } ast::ExprCall(ref f, ref args) => { if bcx.tcx().is_method_call(expr.id) { @@ -1417,7 +1407,7 @@ fn trans_struct<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, numbered_fields.as_slice(), optbase, dest, - Some(NodeInfo { id: expr_id, span: expr_span })) + DebugLoc::At(expr_id, expr_span)) }) } @@ -1448,18 +1438,13 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, fields: &[(uint, &ast::Expr)], optbase: Option>, dest: Dest, - source_location: Option) + debug_location: DebugLoc) -> Block<'blk, 'tcx> { let _icx = push_ctxt("trans_adt"); let fcx = bcx.fcx; let repr = adt::represent_type(bcx.ccx(), ty); - match source_location { - Some(src_loc) => debuginfo::set_source_location(bcx.fcx, - src_loc.id, - src_loc.span), - None => {} - }; + debug_location.apply(bcx.fcx); // If we don't care about the result, just make a // temporary stack slot @@ -1494,12 +1479,7 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } } - match source_location { - Some(src_loc) => debuginfo::set_source_location(bcx.fcx, - src_loc.id, - src_loc.span), - None => {} - }; + debug_location.apply(bcx.fcx); if ty::type_is_simd(bcx.tcx(), ty) { // This is the constructor of a SIMD type, such types are @@ -1540,7 +1520,7 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, match dest { SaveIn(_) => bcx, Ignore => { - bcx = glue::drop_ty(bcx, addr, ty, source_location); + bcx = glue::drop_ty(bcx, addr, ty, debug_location); base::call_lifetime_end(bcx, addr); bcx } @@ -1579,10 +1559,12 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let un_ty = expr_ty(bcx, expr); + let debug_loc = expr.debug_loc(); + match op { ast::UnNot => { let datum = unpack_datum!(bcx, trans(bcx, sub_expr)); - let llresult = Not(bcx, datum.to_llscalarish(bcx)); + let llresult = Not(bcx, datum.to_llscalarish(bcx), debug_loc); immediate_rvalue_bcx(bcx, llresult, un_ty).to_expr_datumblock() } ast::UnNeg => { @@ -1590,9 +1572,9 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let val = datum.to_llscalarish(bcx); let llneg = { if ty::type_is_fp(un_ty) { - FNeg(bcx, val) + FNeg(bcx, val, debug_loc) } else { - Neg(bcx, val) + Neg(bcx, val, debug_loc) } }; immediate_rvalue_bcx(bcx, llneg, un_ty).to_expr_datumblock() @@ -1691,56 +1673,69 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let rhs = base::cast_shift_expr_rhs(bcx, op, lhs, rhs); + let binop_debug_loc = binop_expr.debug_loc(); + let mut bcx = bcx; let val = match op { ast::BiAdd => { - if is_float { FAdd(bcx, lhs, rhs) } - else { Add(bcx, lhs, rhs) } + if is_float { + FAdd(bcx, lhs, rhs, binop_debug_loc) + } else { + Add(bcx, lhs, rhs, binop_debug_loc) + } } ast::BiSub => { - if is_float { FSub(bcx, lhs, rhs) } - else { Sub(bcx, lhs, rhs) } + if is_float { + FSub(bcx, lhs, rhs, binop_debug_loc) + } else { + Sub(bcx, lhs, rhs, binop_debug_loc) + } } ast::BiMul => { - if is_float { FMul(bcx, lhs, rhs) } - else { Mul(bcx, lhs, rhs) } + if is_float { + FMul(bcx, lhs, rhs, binop_debug_loc) + } else { + Mul(bcx, lhs, rhs, binop_debug_loc) + } } ast::BiDiv => { if is_float { - FDiv(bcx, lhs, rhs) + FDiv(bcx, lhs, rhs, binop_debug_loc) } else { // Only zero-check integers; fp /0 is NaN bcx = base::fail_if_zero_or_overflows(bcx, binop_expr.span, op, lhs, rhs, rhs_t); if is_signed { - SDiv(bcx, lhs, rhs) + SDiv(bcx, lhs, rhs, binop_debug_loc) } else { - UDiv(bcx, lhs, rhs) + UDiv(bcx, lhs, rhs, binop_debug_loc) } } } ast::BiRem => { if is_float { - FRem(bcx, lhs, rhs) + FRem(bcx, lhs, rhs, binop_debug_loc) } else { // Only zero-check integers; fp %0 is NaN bcx = base::fail_if_zero_or_overflows(bcx, binop_expr.span, op, lhs, rhs, rhs_t); if is_signed { - SRem(bcx, lhs, rhs) + SRem(bcx, lhs, rhs, binop_debug_loc) } else { - URem(bcx, lhs, rhs) + URem(bcx, lhs, rhs, binop_debug_loc) } } } - ast::BiBitOr => Or(bcx, lhs, rhs), - ast::BiBitAnd => And(bcx, lhs, rhs), - ast::BiBitXor => Xor(bcx, lhs, rhs), - ast::BiShl => Shl(bcx, lhs, rhs), + ast::BiBitOr => Or(bcx, lhs, rhs, binop_debug_loc), + ast::BiBitAnd => And(bcx, lhs, rhs, binop_debug_loc), + ast::BiBitXor => Xor(bcx, lhs, rhs, binop_debug_loc), + ast::BiShl => Shl(bcx, lhs, rhs, binop_debug_loc), ast::BiShr => { if is_signed { - AShr(bcx, lhs, rhs) - } else { LShr(bcx, lhs, rhs) } + AShr(bcx, lhs, rhs, binop_debug_loc) + } else { + LShr(bcx, lhs, rhs, binop_debug_loc) + } } ast::BiEq | ast::BiNe | ast::BiLt | ast::BiGe | ast::BiLe | ast::BiGt => { if ty::type_is_scalar(rhs_t) { @@ -1786,8 +1781,8 @@ fn trans_lazy_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let before_rhs = fcx.new_id_block("before_rhs", b.id); match op { - lazy_and => CondBr(past_lhs, lhs, before_rhs.llbb, join.llbb), - lazy_or => CondBr(past_lhs, lhs, join.llbb, before_rhs.llbb) + lazy_and => CondBr(past_lhs, lhs, before_rhs.llbb, join.llbb, DebugLoc::None), + lazy_or => CondBr(past_lhs, lhs, join.llbb, before_rhs.llbb, DebugLoc::None) } let DatumBlock {bcx: past_rhs, datum: rhs} = trans(before_rhs, b); @@ -1797,7 +1792,7 @@ fn trans_lazy_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, return immediate_rvalue_bcx(join, lhs, binop_ty).to_expr_datumblock(); } - Br(past_rhs, join.llbb); + Br(past_rhs, join.llbb, DebugLoc::None); let phi = Phi(join, Type::i1(bcx.ccx()), &[lhs, rhs], &[past_lhs.llbb, past_rhs.llbb]); diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index d3f3f34b76b..fb2ee55940d 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -29,7 +29,7 @@ use trans::consts; use trans::common::*; use trans::datum; -use trans::debuginfo; +use trans::debuginfo::DebugLoc; use trans::expr; use trans::machine::*; use trans::tvec; @@ -106,7 +106,7 @@ pub fn get_drop_glue_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, pub fn drop_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v: ValueRef, t: Ty<'tcx>, - source_location: Option) + debug_loc: DebugLoc) -> Block<'blk, 'tcx> { // NB: v is an *alias* of type t here, not a direct value. debug!("drop_ty(t={})", t.repr(bcx.tcx())); @@ -121,12 +121,7 @@ pub fn drop_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v }; - match source_location { - Some(sl) => debuginfo::set_source_location(bcx.fcx, sl.id, sl.span), - None => debuginfo::clear_source_location(bcx.fcx) - }; - - Call(bcx, glue, &[ptr], None); + Call(bcx, glue, &[ptr], None, debug_loc); } bcx } @@ -134,12 +129,12 @@ pub fn drop_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pub fn drop_ty_immediate<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v: ValueRef, t: Ty<'tcx>, - source_location: Option) + debug_loc: DebugLoc) -> Block<'blk, 'tcx> { let _icx = push_ctxt("drop_ty_immediate"); let vp = alloca(bcx, type_of(bcx.ccx(), t), ""); store_ty(bcx, v, vp, t); - drop_ty(bcx, vp, t, source_location) + drop_ty(bcx, vp, t, debug_loc) } pub fn get_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> ValueRef { @@ -295,7 +290,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, class_did, &[get_drop_glue_type(bcx.ccx(), t)], ty::mk_nil(bcx.tcx())); - let (_, variant_cx) = invoke(variant_cx, dtor_addr, &args[], dtor_ty, None); + let (_, variant_cx) = invoke(variant_cx, dtor_addr, &args[], dtor_ty, DebugLoc::None); variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope); variant_cx @@ -331,7 +326,7 @@ fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, info: let (unsized_size, unsized_align) = size_and_align_of_dst(bcx, field_ty, info); // Return the sum of sizes and max of aligns. - let size = Add(bcx, sized_size, unsized_size); + let size = Add(bcx, sized_size, unsized_size, DebugLoc::None); let align = Select(bcx, ICmp(bcx, llvm::IntULT, sized_align, unsized_align), sized_align, @@ -353,7 +348,8 @@ fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, info: let llunit_ty = sizing_type_of(bcx.ccx(), unit_ty); let unit_align = llalign_of_min(bcx.ccx(), llunit_ty); let unit_size = llsize_of_alloc(bcx.ccx(), llunit_ty); - (Mul(bcx, info, C_uint(bcx.ccx(), unit_size)), C_uint(bcx.ccx(), unit_align)) + (Mul(bcx, info, C_uint(bcx.ccx(), unit_size), DebugLoc::None), + C_uint(bcx.ccx(), unit_align)) } _ => bcx.sess().bug(&format!("Unexpected unsized type, found {}", bcx.ty_to_string(t))[]) @@ -384,7 +380,8 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>) Call(bcx, dtor, &[PointerCast(bcx, lluniquevalue, Type::i8p(bcx.ccx()))], - None); + None, + DebugLoc::None); bcx }) } @@ -393,7 +390,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>) let llbox = Load(bcx, llval); let not_null = IsNotNull(bcx, llbox); with_cond(bcx, not_null, |bcx| { - let bcx = drop_ty(bcx, v0, content_ty, None); + let bcx = drop_ty(bcx, v0, content_ty, DebugLoc::None); let info = GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]); let info = Load(bcx, info); let (llsize, llalign) = size_and_align_of_dst(bcx, content_ty, info); @@ -406,7 +403,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>) let llbox = Load(bcx, llval); let not_null = IsNotNull(bcx, llbox); with_cond(bcx, not_null, |bcx| { - let bcx = drop_ty(bcx, llbox, content_ty, None); + let bcx = drop_ty(bcx, llbox, content_ty, DebugLoc::None); trans_exchange_free_ty(bcx, llbox, content_ty) }) } @@ -437,14 +434,16 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>) } ty::NoDtor => { // No dtor? Just the default case - iter_structural_ty(bcx, v0, t, |bb, vv, tt| drop_ty(bb, vv, tt, None)) + iter_structural_ty(bcx, v0, t, |bb, vv, tt| drop_ty(bb, vv, tt, DebugLoc::None)) } } } - ty::ty_unboxed_closure(..) => iter_structural_ty(bcx, - v0, - t, - |bb, vv, tt| drop_ty(bb, vv, tt, None)), + ty::ty_unboxed_closure(..) => { + iter_structural_ty(bcx, + v0, + t, + |bb, vv, tt| drop_ty(bb, vv, tt, DebugLoc::None)) + } ty::ty_trait(..) => { // No need to do a null check here (as opposed to the Box(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>) Call(bcx, dtor, &[PointerCast(bcx, Load(bcx, lluniquevalue), Type::i8p(bcx.ccx()))], - None); + None, + DebugLoc::None); bcx }, ty::ty_vec(_, None) | ty::ty_str => { @@ -465,9 +465,11 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>) }, _ => { assert!(type_is_sized(bcx.tcx(), t)); - if type_needs_drop(bcx.tcx(), t) && - ty::type_is_structural(t) { - iter_structural_ty(bcx, v0, t, |bb, vv, tt| drop_ty(bb, vv, tt, None)) + if type_needs_drop(bcx.tcx(), t) && ty::type_is_structural(t) { + iter_structural_ty(bcx, + v0, + t, + |bb, vv, tt| drop_ty(bb, vv, tt, DebugLoc::None)) } else { bcx } @@ -559,7 +561,7 @@ fn make_generic_glue<'a, 'tcx, F>(ccx: &CrateContext<'a, 'tcx>, let llrawptr0 = get_param(llfn, fcx.arg_pos(0) as c_uint); let bcx = helper(bcx, llrawptr0, t); - finish_fn(&fcx, bcx, ty::FnConverging(ty::mk_nil(ccx.tcx()))); + finish_fn(&fcx, bcx, ty::FnConverging(ty::mk_nil(ccx.tcx())), DebugLoc::None); llfn } diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 771c51d629f..9bee2c5bbc6 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -21,6 +21,7 @@ use trans::cleanup::CleanupMethods; use trans::common::*; use trans::datum::*; +use trans::debuginfo::DebugLoc; use trans::expr; use trans::glue; use trans::type_of::*; @@ -149,9 +150,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, args: callee::CallArgs<'a, 'tcx>, dest: expr::Dest, substs: subst::Substs<'tcx>, - call_info: NodeInfo) - -> Result<'blk, 'tcx> -{ + call_info: NodeIdAndSpan) + -> Result<'blk, 'tcx> { let fcx = bcx.fcx; let ccx = fcx.ccx; let tcx = bcx.tcx(); @@ -270,10 +270,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, fcx.pop_custom_cleanup_scope(cleanup_scope); + let call_debug_location = DebugLoc::At(call_info.id, call_info.span); + // These are the only intrinsic functions that diverge. if name.get() == "abort" { let llfn = ccx.get_intrinsic(&("llvm.trap")); - Call(bcx, llfn, &[], None); + Call(bcx, llfn, &[], None, call_debug_location); Unreachable(bcx); return Result::new(bcx, C_undef(Type::nil(ccx).ptr_to())); } else if name.get() == "unreachable" { @@ -304,11 +306,11 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let simple = get_simple_intrinsic(ccx, &*foreign_item); let llval = match (simple, name.get()) { (Some(llfn), _) => { - Call(bcx, llfn, llargs.as_slice(), None) + Call(bcx, llfn, llargs.as_slice(), None, call_debug_location) } (_, "breakpoint") => { let llfn = ccx.get_intrinsic(&("llvm.debugtrap")); - Call(bcx, llfn, &[], None) + Call(bcx, llfn, &[], None, call_debug_location) } (_, "size_of") => { let tp_ty = *substs.types.get(FnSpace, 0); @@ -384,29 +386,63 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } (_, "copy_nonoverlapping_memory") => { - copy_intrinsic(bcx, false, false, *substs.types.get(FnSpace, 0), - llargs[0], llargs[1], llargs[2]) + copy_intrinsic(bcx, + false, + false, + *substs.types.get(FnSpace, 0), + llargs[0], + llargs[1], + llargs[2], + call_debug_location) } (_, "copy_memory") => { - copy_intrinsic(bcx, true, false, *substs.types.get(FnSpace, 0), - llargs[0], llargs[1], llargs[2]) + copy_intrinsic(bcx, + true, + false, + *substs.types.get(FnSpace, 0), + llargs[0], + llargs[1], + llargs[2], + call_debug_location) } (_, "set_memory") => { - memset_intrinsic(bcx, false, *substs.types.get(FnSpace, 0), - llargs[0], llargs[1], llargs[2]) + memset_intrinsic(bcx, + false, + *substs.types.get(FnSpace, 0), + llargs[0], + llargs[1], + llargs[2], + call_debug_location) } (_, "volatile_copy_nonoverlapping_memory") => { - copy_intrinsic(bcx, false, true, *substs.types.get(FnSpace, 0), - llargs[0], llargs[1], llargs[2]) + copy_intrinsic(bcx, + false, + true, + *substs.types.get(FnSpace, 0), + llargs[0], + llargs[1], + llargs[2], + call_debug_location) } (_, "volatile_copy_memory") => { - copy_intrinsic(bcx, true, true, *substs.types.get(FnSpace, 0), - llargs[0], llargs[1], llargs[2]) + copy_intrinsic(bcx, + true, + true, + *substs.types.get(FnSpace, 0), + llargs[0], + llargs[1], + llargs[2], + call_debug_location) } (_, "volatile_set_memory") => { - memset_intrinsic(bcx, true, *substs.types.get(FnSpace, 0), - llargs[0], llargs[1], llargs[2]) + memset_intrinsic(bcx, + true, + *substs.types.get(FnSpace, 0), + llargs[0], + llargs[1], + llargs[2], + call_debug_location) } (_, "volatile_load") => { VolatileLoad(bcx, llargs[0]) @@ -416,93 +452,208 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, C_nil(ccx) }, - (_, "ctlz8") => count_zeros_intrinsic(bcx, "llvm.ctlz.i8", llargs[0]), - (_, "ctlz16") => count_zeros_intrinsic(bcx, "llvm.ctlz.i16", llargs[0]), - (_, "ctlz32") => count_zeros_intrinsic(bcx, "llvm.ctlz.i32", llargs[0]), - (_, "ctlz64") => count_zeros_intrinsic(bcx, "llvm.ctlz.i64", llargs[0]), - (_, "cttz8") => count_zeros_intrinsic(bcx, "llvm.cttz.i8", llargs[0]), - (_, "cttz16") => count_zeros_intrinsic(bcx, "llvm.cttz.i16", llargs[0]), - (_, "cttz32") => count_zeros_intrinsic(bcx, "llvm.cttz.i32", llargs[0]), - (_, "cttz64") => count_zeros_intrinsic(bcx, "llvm.cttz.i64", llargs[0]), + (_, "ctlz8") => count_zeros_intrinsic(bcx, + "llvm.ctlz.i8", + llargs[0], + call_debug_location), + (_, "ctlz16") => count_zeros_intrinsic(bcx, + "llvm.ctlz.i16", + llargs[0], + call_debug_location), + (_, "ctlz32") => count_zeros_intrinsic(bcx, + "llvm.ctlz.i32", + llargs[0], + call_debug_location), + (_, "ctlz64") => count_zeros_intrinsic(bcx, + "llvm.ctlz.i64", + llargs[0], + call_debug_location), + (_, "cttz8") => count_zeros_intrinsic(bcx, + "llvm.cttz.i8", + llargs[0], + call_debug_location), + (_, "cttz16") => count_zeros_intrinsic(bcx, + "llvm.cttz.i16", + llargs[0], + call_debug_location), + (_, "cttz32") => count_zeros_intrinsic(bcx, + "llvm.cttz.i32", + llargs[0], + call_debug_location), + (_, "cttz64") => count_zeros_intrinsic(bcx, + "llvm.cttz.i64", + llargs[0], + call_debug_location), (_, "i8_add_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i8", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.sadd.with.overflow.i8", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "i16_add_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i16", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.sadd.with.overflow.i16", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "i32_add_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i32", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.sadd.with.overflow.i32", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "i64_add_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i64", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.sadd.with.overflow.i64", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "u8_add_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i8", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.uadd.with.overflow.i8", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "u16_add_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i16", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.uadd.with.overflow.i16", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "u32_add_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i32", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.uadd.with.overflow.i32", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "u64_add_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i64", ret_ty, - llargs[0], llargs[1]), - + with_overflow_intrinsic(bcx, + "llvm.uadd.with.overflow.i64", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "i8_sub_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i8", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.ssub.with.overflow.i8", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "i16_sub_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i16", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.ssub.with.overflow.i16", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "i32_sub_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i32", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.ssub.with.overflow.i32", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "i64_sub_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i64", ret_ty, - llargs[0], llargs[1]), - + with_overflow_intrinsic(bcx, + "llvm.ssub.with.overflow.i64", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "u8_sub_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i8", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.usub.with.overflow.i8", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "u16_sub_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i16", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.usub.with.overflow.i16", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "u32_sub_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i32", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.usub.with.overflow.i32", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "u64_sub_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i64", ret_ty, - llargs[0], llargs[1]), - + with_overflow_intrinsic(bcx, + "llvm.usub.with.overflow.i64", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "i8_mul_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i8", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.smul.with.overflow.i8", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "i16_mul_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i16", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.smul.with.overflow.i16", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "i32_mul_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i32", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.smul.with.overflow.i32", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "i64_mul_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i64", ret_ty, - llargs[0], llargs[1]), - + with_overflow_intrinsic(bcx, + "llvm.smul.with.overflow.i64", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "u8_mul_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i8", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.umul.with.overflow.i8", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "u16_mul_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i16", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.umul.with.overflow.i16", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "u32_mul_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i32", ret_ty, - llargs[0], llargs[1]), + with_overflow_intrinsic(bcx, + "llvm.umul.with.overflow.i32", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "u64_mul_with_overflow") => - with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i64", ret_ty, - llargs[0], llargs[1]), - + with_overflow_intrinsic(bcx, + "llvm.umul.with.overflow.i64", + ret_ty, + llargs[0], + llargs[1], + call_debug_location), (_, "return_address") => { if !fcx.caller_expects_out_pointer { tcx.sess.span_err(call_info.span, @@ -609,7 +760,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, // If we made a temporary stack slot, let's clean it up match dest { expr::Ignore => { - bcx = glue::drop_ty(bcx, llresult, ret_ty, Some(call_info)); + bcx = glue::drop_ty(bcx, llresult, ret_ty, call_debug_location); } expr::SaveIn(_) => {} } @@ -618,8 +769,14 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } fn copy_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - allow_overlap: bool, volatile: bool, tp_ty: Ty<'tcx>, - dst: ValueRef, src: ValueRef, count: ValueRef) -> ValueRef { + allow_overlap: bool, + volatile: bool, + tp_ty: Ty<'tcx>, + dst: ValueRef, + src: ValueRef, + count: ValueRef, + call_debug_location: DebugLoc) + -> ValueRef { let ccx = bcx.ccx(); let lltp_ty = type_of::type_of(ccx, tp_ty); let align = C_i32(ccx, type_of::align_of(ccx, tp_ty) as i32); @@ -643,12 +800,25 @@ fn copy_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let src_ptr = PointerCast(bcx, src, Type::i8p(ccx)); let llfn = ccx.get_intrinsic(&name); - Call(bcx, llfn, &[dst_ptr, src_ptr, Mul(bcx, size, count), align, - C_bool(ccx, volatile)], None) + Call(bcx, + llfn, + &[dst_ptr, + src_ptr, + Mul(bcx, size, count, DebugLoc::None), + align, + C_bool(ccx, volatile)], + None, + call_debug_location) } -fn memset_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, volatile: bool, tp_ty: Ty<'tcx>, - dst: ValueRef, val: ValueRef, count: ValueRef) -> ValueRef { +fn memset_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, + volatile: bool, + tp_ty: Ty<'tcx>, + dst: ValueRef, + val: ValueRef, + count: ValueRef, + call_debug_location: DebugLoc) + -> ValueRef { let ccx = bcx.ccx(); let lltp_ty = type_of::type_of(ccx, tp_ty); let align = C_i32(ccx, type_of::align_of(ccx, tp_ty) as i32); @@ -662,22 +832,38 @@ fn memset_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, volatile: bool, tp_ty: T let dst_ptr = PointerCast(bcx, dst, Type::i8p(ccx)); let llfn = ccx.get_intrinsic(&name); - Call(bcx, llfn, &[dst_ptr, val, Mul(bcx, size, count), align, - C_bool(ccx, volatile)], None) + Call(bcx, + llfn, + &[dst_ptr, + val, + Mul(bcx, size, count, DebugLoc::None), + align, + C_bool(ccx, volatile)], + None, + call_debug_location) } -fn count_zeros_intrinsic(bcx: Block, name: &'static str, val: ValueRef) -> ValueRef { +fn count_zeros_intrinsic(bcx: Block, + name: &'static str, + val: ValueRef, + call_debug_location: DebugLoc) + -> ValueRef { let y = C_bool(bcx.ccx(), false); let llfn = bcx.ccx().get_intrinsic(&name); - Call(bcx, llfn, &[val, y], None) + Call(bcx, llfn, &[val, y], None, call_debug_location) } -fn with_overflow_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, name: &'static str, - t: Ty<'tcx>, a: ValueRef, b: ValueRef) -> ValueRef { +fn with_overflow_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, + name: &'static str, + t: Ty<'tcx>, + a: ValueRef, + b: ValueRef, + call_debug_location: DebugLoc) + -> ValueRef { let llfn = bcx.ccx().get_intrinsic(&name); // Convert `i1` to a `bool`, and write it to the out parameter - let val = Call(bcx, llfn, &[a, b], None); + let val = Call(bcx, llfn, &[a, b], None, call_debug_location); let result = ExtractValue(bcx, val, 0); let overflow = ZExt(bcx, ExtractValue(bcx, val, 1), Type::bool(bcx.ccx())); let ret = C_undef(type_of::type_of(bcx.ccx(), t)); diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 0fb0dffe930..c2f19670e4f 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -24,6 +24,7 @@ use trans::cleanup; use trans::common::*; use trans::datum::*; +use trans::debuginfo::DebugLoc; use trans::expr::{SaveIn, Ignore}; use trans::expr; use trans::glue; @@ -494,7 +495,7 @@ pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ty::ty_bare_fn(_, ref f) if f.abi == Rust || f.abi == RustCall => { let fake_sig = ty::Binder(ty::FnSig { - inputs: f.sig.0.inputs.slice_from(1).to_vec(), + inputs: f.sig.0.inputs[1..].to_vec(), output: f.sig.0.output, variadic: f.sig.0.variadic, }); @@ -634,7 +635,7 @@ pub fn trans_object_shim<'a, 'tcx>( } _ => { // skip the self parameter: - sig.inputs.slice_from(1) + &sig.inputs[1..] } }; @@ -676,7 +677,7 @@ pub fn trans_object_shim<'a, 'tcx>( ArgVals(llargs.as_slice()), dest).bcx; - finish_fn(&fcx, bcx, sig.output); + finish_fn(&fcx, bcx, sig.output, DebugLoc::None); (llfn, method_bare_fn_ty) } @@ -785,7 +786,7 @@ pub fn make_vtable>(ccx: &CrateContext, unsafe { let tbl = C_struct(ccx, &components[], false); let sym = token::gensym("vtable"); - let buf = CString::from_vec(format!("vtable{}", sym.uint()).into_bytes()); + let buf = CString::from_vec(format!("vtable{}", sym.usize()).into_bytes()); let vt_gvar = llvm::LLVMAddGlobal(ccx.llmod(), val_ty(tbl).to_ref(), buf.as_ptr()); llvm::LLVMSetInitializer(vt_gvar, tbl); diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index f52e7c0ec94..93076260349 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -274,7 +274,6 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ast_map::NodeArg(..) | ast_map::NodeBlock(..) | ast_map::NodePat(..) | - ast_map::NodeViewItem(..) | ast_map::NodeLocal(..) => { ccx.sess().bug(&format!("can't monomorphize a {:?}", map_node)[]) diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index f8b01ebf4cc..06bc19f45a4 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -21,6 +21,7 @@ use trans::common::*; use trans::consts; use trans::datum::*; +use trans::debuginfo::DebugLoc; use trans::expr::{Dest, Ignore, SaveIn}; use trans::expr; use trans::glue; @@ -58,7 +59,11 @@ pub fn make_drop_glue_unboxed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let dataptr = get_dataptr(bcx, vptr); let bcx = if type_needs_drop(tcx, unit_ty) { let len = get_len(bcx, vptr); - iter_vec_raw(bcx, dataptr, unit_ty, len, |bb, vv, tt| glue::drop_ty(bb, vv, tt, None)) + iter_vec_raw(bcx, + dataptr, + unit_ty, + len, + |bb, vv, tt| glue::drop_ty(bb, vv, tt, DebugLoc::None)) } else { bcx }; @@ -71,7 +76,7 @@ pub fn make_drop_glue_unboxed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let not_empty = ICmp(bcx, llvm::IntNE, len, C_uint(ccx, 0u)); with_cond(bcx, not_empty, |bcx| { let llalign = C_uint(ccx, machine::llalign_of_min(ccx, llty)); - let size = Mul(bcx, C_uint(ccx, unit_size), len); + let size = Mul(bcx, C_uint(ccx, unit_size), len, DebugLoc::None); glue::trans_exchange_free_dyn(bcx, dataptr, size, llalign) }) } else { @@ -420,14 +425,14 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, let cond_bcx = fcx.new_temp_block("expr_repeat: loop cond"); let body_bcx = fcx.new_temp_block("expr_repeat: body: set"); let inc_bcx = fcx.new_temp_block("expr_repeat: body: inc"); - Br(bcx, loop_bcx.llbb); + Br(bcx, loop_bcx.llbb, DebugLoc::None); let loop_counter = { // i = 0 let i = alloca(loop_bcx, bcx.ccx().int_type(), "__i"); Store(loop_bcx, C_uint(bcx.ccx(), 0u), i); - Br(loop_bcx, cond_bcx.llbb); + Br(loop_bcx, cond_bcx.llbb, DebugLoc::None); i }; @@ -436,7 +441,7 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, let rhs = count; let cond_val = ICmp(cond_bcx, llvm::IntULT, lhs, rhs); - CondBr(cond_bcx, cond_val, body_bcx.llbb, next_bcx.llbb); + CondBr(cond_bcx, cond_val, body_bcx.llbb, next_bcx.llbb, DebugLoc::None); } { // loop body @@ -448,15 +453,15 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, }; let body_bcx = f(body_bcx, lleltptr, vt.unit_ty); - Br(body_bcx, inc_bcx.llbb); + Br(body_bcx, inc_bcx.llbb, DebugLoc::None); } { // i += 1 let i = Load(inc_bcx, loop_counter); - let plusone = Add(inc_bcx, i, C_uint(bcx.ccx(), 1u)); + let plusone = Add(inc_bcx, i, C_uint(bcx.ccx(), 1u), DebugLoc::None); Store(inc_bcx, plusone, loop_counter); - Br(inc_bcx, cond_bcx.llbb); + Br(inc_bcx, cond_bcx.llbb, DebugLoc::None); } next_bcx @@ -484,19 +489,19 @@ pub fn iter_vec_raw<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, // Now perform the iteration. let header_bcx = fcx.new_temp_block("iter_vec_loop_header"); - Br(bcx, header_bcx.llbb); + Br(bcx, header_bcx.llbb, DebugLoc::None); let data_ptr = Phi(header_bcx, val_ty(data_ptr), &[data_ptr], &[bcx.llbb]); let not_yet_at_end = ICmp(header_bcx, llvm::IntULT, data_ptr, data_end_ptr); let body_bcx = fcx.new_temp_block("iter_vec_loop_body"); let next_bcx = fcx.new_temp_block("iter_vec_next"); - CondBr(header_bcx, not_yet_at_end, body_bcx.llbb, next_bcx.llbb); + CondBr(header_bcx, not_yet_at_end, body_bcx.llbb, next_bcx.llbb, DebugLoc::None); let body_bcx = f(body_bcx, data_ptr, vt.unit_ty); AddIncomingToPhi(data_ptr, InBoundsGEP(body_bcx, data_ptr, &[C_int(bcx.ccx(), 1i)]), body_bcx.llbb); - Br(body_bcx, header_bcx.llbb); + Br(body_bcx, header_bcx.llbb, DebugLoc::None); next_bcx } } diff --git a/src/librustc_trans/trans/type_.rs b/src/librustc_trans/trans/type_.rs index 07eb17e6300..9640443f4f7 100644 --- a/src/librustc_trans/trans/type_.rs +++ b/src/librustc_trans/trans/type_.rs @@ -21,6 +21,7 @@ use std::ffi::CString; use std::mem; +use std::ptr; use std::cell::RefCell; use std::iter::repeat; @@ -227,14 +228,6 @@ pub fn opaque_vec(ccx: &CrateContext) -> Type { Type::vec(ccx, &Type::i8(ccx)) } - // The box pointed to by @T. - pub fn at_box(ccx: &CrateContext, ty: Type) -> Type { - Type::struct_(ccx, &[ - ccx.int_type(), Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to(), - Type::i8p(ccx), Type::i8p(ccx), ty - ], false) - } - pub fn vtable_ptr(ccx: &CrateContext) -> Type { Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to().ptr_to() } @@ -303,7 +296,7 @@ pub fn field_types(&self) -> Vec { if n_elts == 0 { return Vec::new(); } - let mut elts: Vec<_> = repeat(Type { rf: 0 as TypeRef }).take(n_elts).collect(); + let mut elts: Vec<_> = repeat(Type { rf: ptr::null_mut() }).take(n_elts).collect(); llvm::LLVMGetStructElementTypes(self.to_ref(), elts.as_mut_ptr() as *mut TypeRef); elts @@ -317,7 +310,7 @@ pub fn return_type(&self) -> Type { pub fn func_params(&self) -> Vec { unsafe { let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as uint; - let mut args: Vec<_> = repeat(Type { rf: 0 as TypeRef }).take(n_args).collect(); + let mut args: Vec<_> = repeat(Type { rf: ptr::null_mut() }).take(n_args).collect(); llvm::LLVMGetParamTypes(self.to_ref(), args.as_mut_ptr() as *mut TypeRef); args diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 42b12c15866..921ed505fa3 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -100,8 +100,7 @@ fn projected_ty_from_poly_trait_ref(&self, -> Ty<'tcx> { if ty::binds_late_bound_regions(self.tcx(), &poly_trait_ref) { - self.tcx().sess.span_err( - span, + span_err!(self.tcx().sess, span, E0212, "cannot extract an associated type from a higher-ranked trait bound \ in this context"); self.tcx().types.err @@ -119,8 +118,7 @@ fn projected_ty(&self, _item_name: ast::Name) -> Ty<'tcx> { - self.tcx().sess.span_err( - span, + span_err!(self.tcx().sess, span, E0213, "associated types are not accepted in this context"); self.tcx().types.err @@ -268,8 +266,7 @@ pub fn ast_path_substs_for_ty<'tcx>( convert_angle_bracketed_parameters(this, rscope, data) } ast::ParenthesizedParameters(ref data) => { - tcx.sess.span_err( - path.span, + span_err!(tcx.sess, path.span, E0214, "parenthesized parameters may only be used with a trait"); (Vec::new(), convert_parenthesized_parameters(this, data), Vec::new()) } @@ -342,22 +339,22 @@ fn create_substs_for_ast_path<'tcx>( } else { "expected" }; - this.tcx().sess.span_fatal(span, - &format!("wrong number of type arguments: {} {}, found {}", + span_fatal!(this.tcx().sess, span, E0243, + "wrong number of type arguments: {} {}, found {}", expected, required_ty_param_count, - supplied_ty_param_count)[]); + supplied_ty_param_count); } else if supplied_ty_param_count > formal_ty_param_count { let expected = if required_ty_param_count < formal_ty_param_count { "expected at most" } else { "expected" }; - this.tcx().sess.span_fatal(span, - &format!("wrong number of type arguments: {} {}, found {}", + span_fatal!(this.tcx().sess, span, E0244, + "wrong number of type arguments: {} {}, found {}", expected, formal_ty_param_count, - supplied_ty_param_count)[]); + supplied_ty_param_count); } let mut substs = Substs::new_type(types, regions); @@ -560,10 +557,9 @@ pub fn instantiate_trait_ref<'tcx>( trait_ref } _ => { - this.tcx().sess.span_fatal( - ast_trait_ref.path.span, - &format!("`{}` is not a trait", - ast_trait_ref.path.user_string(this.tcx()))[]); + span_fatal!(this.tcx().sess, ast_trait_ref.path.span, E0245, + "`{}` is not a trait", + ast_trait_ref.path.user_string(this.tcx())); } } } @@ -610,7 +606,7 @@ fn ast_path_to_trait_ref<'a,'tcx>( if !this.tcx().sess.features.borrow().unboxed_closures && this.tcx().lang_items.fn_trait_kind(trait_def_id).is_some() { - this.tcx().sess.span_err(path.span, + span_err!(this.tcx().sess, path.span, E0215, "angle-bracket notation is not stable when \ used with the `Fn` family of traits, use parentheses"); span_help!(this.tcx().sess, path.span, @@ -626,7 +622,7 @@ fn ast_path_to_trait_ref<'a,'tcx>( if !this.tcx().sess.features.borrow().unboxed_closures && this.tcx().lang_items.fn_trait_kind(trait_def_id).is_none() { - this.tcx().sess.span_err(path.span, + span_err!(this.tcx().sess, path.span, E0216, "parenthetical notation is only stable when \ used with the `Fn` family of traits"); span_help!(this.tcx().sess, path.span, @@ -738,32 +734,29 @@ fn ast_type_binding_to_projection_predicate<'tcx>( } if candidates.len() > 1 { - tcx.sess.span_err( - binding.span, - format!("ambiguous associated type: `{}` defined in multiple supertraits `{}`", + span_err!(tcx.sess, binding.span, E0217, + "ambiguous associated type: `{}` defined in multiple supertraits `{}`", token::get_name(binding.item_name), - candidates.user_string(tcx)).as_slice()); + candidates.user_string(tcx)); return Err(ErrorReported); } let candidate = match candidates.pop() { Some(c) => c, None => { - tcx.sess.span_err( - binding.span, - format!("no associated type `{}` defined in `{}`", + span_err!(tcx.sess, binding.span, E0218, + "no associated type `{}` defined in `{}`", token::get_name(binding.item_name), - trait_ref.user_string(tcx)).as_slice()); + trait_ref.user_string(tcx)); return Err(ErrorReported); } }; if ty::binds_late_bound_regions(tcx, &candidate) { - tcx.sess.span_err( - binding.span, - format!("associated type `{}` defined in higher-ranked supertrait `{}`", + span_err!(tcx.sess, binding.span, E0219, + "associated type `{}` defined in higher-ranked supertrait `{}`", token::get_name(binding.item_name), - candidate.user_string(tcx)).as_slice()); + candidate.user_string(tcx)); return Err(ErrorReported); } @@ -893,14 +886,14 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>, pprust::ty_to_string(ty)); match ty.node { ast::TyRptr(None, ref mut_ty) => { - span_note!(this.tcx().sess, ty.span, + span_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_note!(this.tcx().sess, ty.span, + span_help!(this.tcx().sess, ty.span, "perhaps you meant `&{} {}({} +{})`? (per RFC 438)", pprust::lifetime_to_string(lt), ppaux::mutability_to_string(mut_ty.mutbl), @@ -909,7 +902,7 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>, } _ => { - span_note!(this.tcx().sess, ty.span, + span_help!(this.tcx().sess, ty.span, "perhaps you forgot parentheses? (per RFC 438)"); } } @@ -964,18 +957,18 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>, } if suitable_bounds.len() == 0 { - tcx.sess.span_err(ast_ty.span, - format!("associated type `{}` not found for type parameter `{}`", + span_err!(tcx.sess, ast_ty.span, E0220, + "associated type `{}` not found for type parameter `{}`", token::get_name(assoc_name), - token::get_name(ty_param_name)).as_slice()); + token::get_name(ty_param_name)); return this.tcx().types.err; } if suitable_bounds.len() > 1 { - tcx.sess.span_err(ast_ty.span, - format!("ambiguous associated type `{}` in bounds of `{}`", + span_err!(tcx.sess, ast_ty.span, E0221, + "ambiguous associated type `{}` in bounds of `{}`", token::get_name(assoc_name), - token::get_name(ty_param_name)).as_slice()); + token::get_name(ty_param_name)); for suitable_bound in suitable_bounds.iter() { span_note!(this.tcx().sess, ast_ty.span, @@ -1042,7 +1035,7 @@ pub fn ast_ty_to_ty<'tcx>( match ast_ty_to_ty_cache.get(&ast_ty.id) { Some(&ty::atttce_resolved(ty)) => return ty, Some(&ty::atttce_unresolved) => { - tcx.sess.span_fatal(ast_ty.span, + span_fatal!(tcx.sess, ast_ty.span, E0246, "illegal recursive type; insert an enum \ or struct in the cycle, if this is \ desired"); @@ -1093,7 +1086,7 @@ pub fn ast_ty_to_ty<'tcx>( ast::TyParen(ref typ) => ast_ty_to_ty(this, rscope, &**typ), ast::TyBareFn(ref bf) => { if bf.decl.variadic && bf.abi != abi::C { - tcx.sess.span_err(ast_ty.span, + span_err!(tcx.sess, ast_ty.span, E0222, "variadic function must have C calling convention"); } let bare_fn = ty_of_bare_fn(this, bf.unsafety, bf.abi, &*bf.decl); @@ -1142,9 +1135,9 @@ pub fn ast_ty_to_ty<'tcx>( ty::mk_self_type(tcx) } def::DefMod(id) => { - tcx.sess.span_fatal(ast_ty.span, - &format!("found module name used as a type: {}", - tcx.map.node_to_string(id.node))[]); + span_fatal!(tcx.sess, ast_ty.span, E0247, + "found module name used as a type: {}", + tcx.map.node_to_string(id.node)); } def::DefPrimTy(_) => { panic!("DefPrimTy arm missed in previous ast_ty_to_prim_ty call"); @@ -1152,8 +1145,8 @@ pub fn ast_ty_to_ty<'tcx>( def::DefAssociatedTy(trait_type_id) => { let path_str = tcx.map.path_to_string( tcx.map.get_parent(trait_type_id.node)); - tcx.sess.span_err(ast_ty.span, - &format!("ambiguous associated \ + span_err!(tcx.sess, ast_ty.span, E0223, + "ambiguous associated \ type; specify the type \ using the syntax `::{}`", @@ -1163,17 +1156,17 @@ pub fn ast_ty_to_ty<'tcx>( .last() .unwrap() .identifier) - .get())[]); + .get()); this.tcx().types.err } def::DefAssociatedPath(provenance, assoc_ident) => { associated_path_def_to_ty(this, ast_ty, provenance, assoc_ident.name) } _ => { - tcx.sess.span_fatal(ast_ty.span, - &format!("found value name used \ + span_fatal!(tcx.sess, ast_ty.span, E0248, + "found value name used \ as a type: {:?}", - a_def)[]); + a_def); } } } @@ -1191,17 +1184,16 @@ pub fn ast_ty_to_ty<'tcx>( ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty), Some(i as uint)), _ => { - tcx.sess.span_fatal( - ast_ty.span, "expected constant expr for array length"); + span_fatal!(tcx.sess, ast_ty.span, E0249, + "expected constant expr for array length"); } } } Err(ref r) => { - tcx.sess.span_fatal( - ast_ty.span, - &format!("expected constant expr for array \ + span_fatal!(tcx.sess, ast_ty.span, E0250, + "expected constant expr for array \ length: {}", - *r)[]); + *r); } } } @@ -1321,7 +1313,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>, // HACK(eddyb) replace the fake self type in the AST with the actual type. let input_params = if self_ty.is_some() { - decl.inputs.slice_from(1) + &decl.inputs[1..] } else { &decl.inputs[] }; @@ -1339,9 +1331,9 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>, let lifetimes_for_params = if implied_output_region.is_none() { let input_tys = if self_ty.is_some() { // Skip the first argument if `self` is present. - self_and_input_tys.slice_from(1) + &self_and_input_tys[1..] } else { - self_and_input_tys.slice_from(0) + &self_and_input_tys[] }; let (ior, lfp) = find_implied_output_region(input_tys, input_pats); @@ -1457,9 +1449,6 @@ fn count_modifiers(ty: Ty) -> uint { pub fn ty_of_closure<'tcx>( this: &AstConv<'tcx>, unsafety: ast::Unsafety, - onceness: ast::Onceness, - bounds: ty::ExistentialBounds<'tcx>, - store: ty::TraitStore, decl: &ast::FnDecl, abi: abi::Abi, expected_sig: Option>) @@ -1509,9 +1498,6 @@ pub fn ty_of_closure<'tcx>( ty::ClosureTy { unsafety: unsafety, - onceness: onceness, - store: store, - bounds: bounds, abi: abi, sig: ty::Binder(ty::FnSig {inputs: input_tys, output: output_ty, @@ -1557,8 +1543,7 @@ fn conv_ty_poly_trait_ref<'tcx>( None, &mut projection_bounds)) } else { - this.tcx().sess.span_err( - span, + span_err!(this.tcx().sess, span, E0224, "at least one non-builtin trait is required for an object type"); None }; @@ -1593,10 +1578,9 @@ pub fn conv_existential_bounds_from_partitioned_bounds<'tcx>( if !trait_bounds.is_empty() { let b = &trait_bounds[0]; - this.tcx().sess.span_err( - b.trait_ref.path.span, - &format!("only the builtin traits can be used \ - as closure or object bounds")[]); + span_err!(this.tcx().sess, b.trait_ref.path.span, E0225, + "only the builtin traits can be used \ + as closure or object bounds"); } let region_bound = compute_region_bound(this, @@ -1633,9 +1617,8 @@ fn compute_opt_region_bound<'tcx>(tcx: &ty::ctxt<'tcx>, builtin_bounds.repr(tcx)); if explicit_region_bounds.len() > 1 { - tcx.sess.span_err( - explicit_region_bounds[1].span, - format!("only a single explicit lifetime bound is permitted").as_slice()); + span_err!(tcx.sess, explicit_region_bounds[1].span, E0226, + "only a single explicit lifetime bound is permitted"); } if explicit_region_bounds.len() != 0 { @@ -1665,11 +1648,10 @@ fn compute_opt_region_bound<'tcx>(tcx: &ty::ctxt<'tcx>, // of derived region bounds. If so, use that. Otherwise, report an // error. let r = derived_region_bounds[0]; - if derived_region_bounds.slice_from(1).iter().any(|r1| r != *r1) { - tcx.sess.span_err( - span, - &format!("ambiguous lifetime bound, \ - explicit lifetime bound required")[]); + if derived_region_bounds[1..].iter().any(|r1| r != *r1) { + span_err!(tcx.sess, span, E0227, + "ambiguous lifetime bound, \ + explicit lifetime bound required"); } return Some(r); } @@ -1693,9 +1675,8 @@ fn compute_region_bound<'tcx>( match rscope.default_region_bound(span) { Some(r) => { r } None => { - this.tcx().sess.span_err( - span, - &format!("explicit lifetime bound required")[]); + span_err!(this.tcx().sess, span, E0228, + "explicit lifetime bound required"); ty::ReStatic } } @@ -1779,8 +1760,7 @@ fn prohibit_projections<'tcx>(tcx: &ty::ctxt<'tcx>, bindings: &[ConvertedBinding<'tcx>]) { for binding in bindings.iter().take(1) { - tcx.sess.span_err( - binding.span, + span_err!(tcx.sess, binding.span, E0229, "associated type bindings are not allowed here"); } } diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index bfe43086aab..ffec1421f92 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -50,10 +50,9 @@ pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, check_unboxed_closure(fcx, expr, kind, decl, body, None); - fcx.ccx.tcx.sess.span_err( - expr.span, - "can't infer the \"kind\" of the closure, explicitly annotate it. e.g. \ - `|&:| {}`"); + span_err!(fcx.ccx.tcx.sess, expr.span, E0187, + "can't infer the \"kind\" of the closure; explicitly annotate it; e.g. \ + `|&:| {{}}`"); }, Some((sig, kind)) => { check_unboxed_closure(fcx, expr, kind, decl, body, Some(sig)); @@ -89,15 +88,6 @@ fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, let mut fn_ty = astconv::ty_of_closure( fcx, ast::Unsafety::Normal, - ast::Many, - - // The `RegionTraitStore` and region_existential_bounds - // are lies, but we ignore them so it doesn't matter. - // - // FIXME(pcwalton): Refactor this API. - ty::region_existential_bound(ty::ReStatic), - ty::RegionTraitStore(ty::ReStatic, ast::MutImmutable), - decl, abi::RustCall, expected_sig); diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 27d4b2055d4..e3e5d67869f 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -59,23 +59,21 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, (&ty::StaticExplicitSelfCategory, &ty::StaticExplicitSelfCategory) => {} (&ty::StaticExplicitSelfCategory, _) => { - tcx.sess.span_err( - impl_m_span, - format!("method `{}` has a `{}` declaration in the impl, \ + span_err!(tcx.sess, impl_m_span, E0185, + "method `{}` has a `{}` declaration in the impl, \ but not in the trait", token::get_name(trait_m.name), ppaux::explicit_self_category_to_str( - &impl_m.explicit_self)).as_slice()); + &impl_m.explicit_self)); return; } (_, &ty::StaticExplicitSelfCategory) => { - tcx.sess.span_err( - impl_m_span, - format!("method `{}` has a `{}` declaration in the trait, \ + span_err!(tcx.sess, impl_m_span, E0186, + "method `{}` has a `{}` declaration in the trait, \ but not in the impl", token::get_name(trait_m.name), ppaux::explicit_self_category_to_str( - &trait_m.explicit_self)).as_slice()); + &trait_m.explicit_self)); return; } _ => { @@ -400,11 +398,10 @@ fn check_region_bounds_on_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, // are zero. Since I don't quite know how to phrase things at // the moment, give a kind of vague error message. if trait_params.len() != impl_params.len() { - tcx.sess.span_err( - span, - &format!("lifetime parameters or bounds on method `{}` do \ + span_err!(tcx.sess, span, E0195, + "lifetime parameters or bounds on method `{}` do \ not match the trait declaration", - token::get_name(impl_m.name))[]); + token::get_name(impl_m.name)); return false; } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 2a89a1d28bf..3cf9a1a9456 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -145,6 +145,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, if !valid_out_of_scope_traits.is_empty() { let mut candidates = valid_out_of_scope_traits; candidates.sort(); + candidates.dedup(); let msg = format!( "methods from traits can only be called if the trait is in scope; \ the following {traits_are} implemented but not in scope, \ @@ -172,6 +173,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, if candidates.len() > 0 { // sort from most relevant to least relevant candidates.sort_by(|a, b| a.cmp(b).reverse()); + candidates.dedup(); let msg = format!( "methods from traits can only be called if the trait is implemented and in scope; \ diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f610456f73c..db4962b0d22 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -801,16 +801,15 @@ fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }) { Some(_) => (), None => { - ccx.tcx.sess.span_err(attr.span, - format!("there is no type parameter \ + span_err!(ccx.tcx.sess, attr.span, E0230, + "there is no type parameter \ {} on trait {}", - s, item.ident.as_str()) - .as_slice()); + s, item.ident.as_str()); } }, // `{:1}` and `{}` are not to be used Position::ArgumentIs(_) | Position::ArgumentNext => { - ccx.tcx.sess.span_err(attr.span, + span_err!(ccx.tcx.sess, attr.span, E0231, "only named substitution \ parameters are allowed"); } @@ -818,7 +817,7 @@ fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } } else { - ccx.tcx.sess.span_err(attr.span, + span_err!(ccx.tcx.sess, attr.span, E0232, "this attribute must have a value, \ eg `#[rustc_on_unimplemented = \"foo\"]`") } @@ -2099,8 +2098,8 @@ fn lookup_method_for_for_loop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let trait_did = match fcx.tcx().lang_items.require(IteratorItem) { Ok(trait_did) => trait_did, Err(ref err_string) => { - fcx.tcx().sess.span_err(iterator_expr.span, - &err_string[]); + span_err!(fcx.tcx().sess, iterator_expr.span, E0233, + "{}", &err_string[]); return fcx.tcx().types.err } }; @@ -2123,11 +2122,10 @@ fn lookup_method_for_for_loop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, if !ty::type_is_error(true_expr_type) { let ty_string = fcx.infcx().ty_to_string(true_expr_type); - fcx.tcx().sess.span_err(iterator_expr.span, - &format!("`for` loop expression has type `{}` which does \ + span_err!(fcx.tcx().sess, iterator_expr.span, E0234, + "`for` loop expression has type `{}` which does \ not implement the `Iterator` trait; \ - maybe try .iter()", - ty_string)[]); + maybe try .iter()", ty_string); } fcx.tcx().types.err } @@ -2162,11 +2160,10 @@ fn lookup_method_for_for_loop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, fcx.tcx().types.err } _ => { - fcx.tcx().sess.span_err(iterator_expr.span, - &format!("`next` method of the `Iterator` \ + span_err!(fcx.tcx().sess, iterator_expr.span, E0239, + "`next` method of the `Iterator` \ trait has an unexpected type `{}`", - fcx.infcx().ty_to_string(return_type)) - []); + fcx.infcx().ty_to_string(return_type)); fcx.tcx().types.err } } @@ -3880,10 +3877,8 @@ fn check_struct_fields_on_error(fcx: &FnCtxt, Err(type_error) => { let type_error_description = ty::type_err_to_str(tcx, &type_error); - fcx.tcx() - .sess - .span_err(path.span, - &format!("structure constructor specifies a \ + span_err!(fcx.tcx().sess, path.span, E0235, + "structure constructor specifies a \ structure of type `{}`, but this \ structure has type `{}`: {}", fcx.infcx() @@ -3891,7 +3886,7 @@ fn check_struct_fields_on_error(fcx: &FnCtxt, fcx.infcx() .ty_to_string( actual_structure_type), - type_error_description)[]); + type_error_description); ty::note_and_explain_type_err(tcx, &type_error); } } @@ -4012,7 +4007,7 @@ fn check_struct_fields_on_error(fcx: &FnCtxt, ty::mk_struct(tcx, did, tcx.mk_substs(substs)) } else { - tcx.sess.span_err(expr.span, "No lang item for range syntax"); + span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax"); fcx.tcx().types.err } } @@ -4022,7 +4017,7 @@ fn check_struct_fields_on_error(fcx: &FnCtxt, let substs = Substs::new_type(vec![], vec![]); ty::mk_struct(tcx, did, tcx.mk_substs(substs)) } else { - tcx.sess.span_err(expr.span, "No lang item for range syntax"); + span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax"); fcx.tcx().types.err } } @@ -4872,8 +4867,7 @@ fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>( } ast::ParenthesizedParameters(ref data) => { - fcx.tcx().sess.span_err( - span, + span_err!(fcx.tcx().sess, span, E0238, "parenthesized parameters may only be used with a trait"); push_explicit_parenthesized_parameters_from_segment_to_substs( fcx, space, span, type_defs, data, substs); @@ -5230,7 +5224,7 @@ fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> { "get_tydesc" => { let tydesc_ty = match ty::get_tydesc_ty(ccx.tcx) { Ok(t) => t, - Err(s) => { tcx.sess.span_fatal(it.span, &s[]); } + Err(s) => { span_fatal!(tcx.sess, it.span, E0240, "{}", &s[]); } }; let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { ty: tydesc_ty, diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 3b5027dbb9e..56b700663d4 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -297,14 +297,25 @@ fn visit_fn_body(&mut self, fn visit_region_obligations(&mut self, node_id: ast::NodeId) { debug!("visit_region_obligations: node_id={}", node_id); - let fulfillment_cx = self.fcx.inh.fulfillment_cx.borrow(); - for r_o in fulfillment_cx.region_obligations(node_id).iter() { + + // Make a copy of the region obligations vec because we'll need + // to be able to borrow the fulfillment-cx below when projecting. + let region_obligations = + self.fcx.inh.fulfillment_cx.borrow() + .region_obligations(node_id) + .to_vec(); + + for r_o in region_obligations.iter() { debug!("visit_region_obligations: r_o={}", r_o.repr(self.tcx())); let sup_type = self.resolve_type(r_o.sup_type); let origin = infer::RelateRegionParamBound(r_o.cause.span); type_must_outlive(self, origin, sup_type, r_o.sub_region); } + + // Processing the region obligations should not cause the list to grow further: + assert_eq!(region_obligations.len(), + self.fcx.inh.fulfillment_cx.borrow().region_obligations(node_id).len()); } /// This method populates the region map's `free_region_map`. It walks over the transformed @@ -531,7 +542,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { ast::ExprMethodCall(_, _, ref args) => { constrain_call(rcx, expr, Some(&*args[0]), - args.slice_from(1).iter().map(|e| &**e), false); + args[1..].iter().map(|e| &**e), false); visit::walk_expr(rcx, expr); } @@ -1480,6 +1491,15 @@ fn generic_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, generic.to_ty(rcx.tcx()), param_env.caller_bounds.predicates.as_slice().to_vec()); + // In the case of a projection T::Foo, we may be able to extract bounds from the trait def: + match *generic { + GenericKind::Param(..) => { } + GenericKind::Projection(ref projection_ty) => { + param_bounds.push_all( + &projection_bounds(rcx, origin.span(), projection_ty)[]); + } + } + // Add in the default bound of fn body that applies to all in // scope type parameters: param_bounds.push(param_env.implicit_region_bound); @@ -1511,3 +1531,73 @@ fn generic_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, region, param_bounds); } + +fn projection_bounds<'a,'tcx>(rcx: &Rcx<'a, 'tcx>, + span: Span, + projection_ty: &ty::ProjectionTy<'tcx>) + -> Vec +{ + let fcx = rcx.fcx; + let tcx = fcx.tcx(); + let infcx = fcx.infcx(); + + debug!("projection_bounds(projection_ty={})", + projection_ty.repr(tcx)); + + let ty = ty::mk_projection(tcx, projection_ty.trait_ref.clone(), projection_ty.item_name); + + // Say we have a projection `>::SomeType`. We are interested + // in looking for a trait definition like: + // + // ``` + // trait SomeTrait<'a> { + // type SomeType : 'a; + // } + // ``` + // + // we can thus deduce that `>::SomeType : 'a`. + let trait_def = ty::lookup_trait_def(tcx, projection_ty.trait_ref.def_id); + let predicates = trait_def.generics.predicates.as_slice().to_vec(); + traits::elaborate_predicates(tcx, predicates) + .filter_map(|predicate| { + // we're only interesting in `T : 'a` style predicates: + let outlives = match predicate { + ty::Predicate::TypeOutlives(data) => data, + _ => { return None; } + }; + + debug!("projection_bounds: outlives={} (1)", + outlives.repr(tcx)); + + // apply the substitutions (and normalize any projected types) + let outlives = fcx.instantiate_type_scheme(span, + projection_ty.trait_ref.substs, + &outlives); + + debug!("projection_bounds: outlives={} (2)", + outlives.repr(tcx)); + + let region_result = infcx.try(|_| { + let (outlives, _) = + infcx.replace_late_bound_regions_with_fresh_var( + span, + infer::AssocTypeProjection(projection_ty.item_name), + &outlives); + + debug!("projection_bounds: outlives={} (3)", + outlives.repr(tcx)); + + // check whether this predicate applies to our current projection + match infer::mk_eqty(infcx, false, infer::Misc(span), ty, outlives.0) { + Ok(()) => { Ok(outlives.1) } + Err(_) => { Err(()) } + } + }); + + debug!("projection_bounds: region_result={}", + region_result.repr(tcx)); + + region_result.ok() + }) + .collect() +} diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index 3940092eb72..41b63830279 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -51,7 +51,7 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, { let object_trait = object_trait(&object_trait_ty); if !mutability_allowed(referent_mutbl, target_mutbl) { - fcx.tcx().sess.span_err(source_expr.span, + span_err!(fcx.tcx().sess, source_expr.span, E0188, "types differ in mutability"); } else { // Ensure that if &'a T is cast to &'b Trait, then T : Trait @@ -70,19 +70,17 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, } (_, &ty::ty_uniq(..)) => { - fcx.ccx.tcx.sess.span_err( - source_expr.span, - &format!("can only cast an boxed pointer \ + span_err!(fcx.ccx.tcx.sess, source_expr.span, E0189, + "can only cast a boxed pointer \ to a boxed object, not a {}", - ty::ty_sort_string(fcx.tcx(), source_ty))[]); + ty::ty_sort_string(fcx.tcx(), source_ty)); } (_, &ty::ty_rptr(..)) => { - fcx.ccx.tcx.sess.span_err( - source_expr.span, - &format!("can only cast a &-pointer \ + span_err!(fcx.ccx.tcx.sess, source_expr.span, E0190, + "can only cast a &-pointer \ to an &-object, not a {}", - ty::ty_sort_string(fcx.tcx(), source_ty))[]); + ty::ty_sort_string(fcx.tcx(), source_ty)); } _ => { @@ -272,11 +270,10 @@ fn check_object_type_binds_all_associated_types<'tcx>(tcx: &ty::ctxt<'tcx>, } for (trait_def_id, name) in associated_types.into_iter() { - tcx.sess.span_err( - span, - format!("the value of the associated type `{}` (from the trait `{}`) must be specified", + span_err!(tcx.sess, span, E0191, + "the value of the associated type `{}` (from the trait `{}`) must be specified", name.user_string(tcx), - ty::item_path_str(tcx, trait_def_id)).as_slice()); + ty::item_path_str(tcx, trait_def_id)); } } diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index e6390212c60..60284433ffe 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -81,10 +81,9 @@ fn check_item_well_formed(&mut self, item: &ast::Item) { match ccx.tcx.lang_items.to_builtin_kind(trait_ref.def_id) { Some(ty::BoundSend) | Some(ty::BoundSync) => {} Some(_) | None => { - ccx.tcx.sess.span_err( - item.span, - format!("negative impls are currently \ - allowed just for `Send` and `Sync`").as_slice()) + span_err!(ccx.tcx.sess, item.span, E0192, + "negative impls are currently \ + allowed just for `Send` and `Sync`") } } } @@ -302,12 +301,11 @@ fn reject_non_type_param_bounds<'tcx>(tcx: &ty::ctxt<'tcx>, fn report_bound_error<'t>(tcx: &ty::ctxt<'t>, span: Span, bounded_ty: ty::Ty<'t>) { - tcx.sess.span_err( - span, - format!("cannot bound type `{}`, where clause \ + span_err!(tcx.sess, span, E0193, + "cannot bound type `{}`, where clause \ bounds may only be attached to types involving \ type parameters", - bounded_ty.repr(tcx)).as_slice()) + bounded_ty.repr(tcx)) } fn is_ty_param(ty: ty::Ty) -> bool { @@ -326,10 +324,9 @@ fn reject_shadowing_type_parameters<'tcx>(tcx: &ty::ctxt<'tcx>, for method_param in generics.types.get_slice(subst::FnSpace).iter() { if impl_params.contains(&method_param.name) { - tcx.sess.span_err( - span, - &*format!("type parameter `{}` shadows another type parameter of the same name", - token::get_name(method_param.name))); + span_err!(tcx.sess, span, E0194, + "type parameter `{}` shadows another type parameter of the same name", + token::get_name(method_param.name)); } } } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 82da22eab98..52e81585875 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -416,7 +416,7 @@ fn report_error(&self, e: infer::fixup_err) { ResolvingUnboxedClosure(_) => { let span = self.reason.span(self.tcx); - self.tcx.sess.span_err(span, + span_err!(self.tcx.sess, span, E0196, "cannot determine a type for this \ unboxed closure") } diff --git a/src/librustc_typeck/coherence/impls.rs b/src/librustc_typeck/coherence/impls.rs index 2719a09f4f5..e535b86a7bf 100644 --- a/src/librustc_typeck/coherence/impls.rs +++ b/src/librustc_typeck/coherence/impls.rs @@ -34,10 +34,9 @@ fn visit_item(&mut self, item: &'v ast::Item) { match trait_ref.self_ty().sty { ty::ty_struct(..) | ty::ty_enum(..) => {} _ => { - self.tcx.sess.span_err( - item.span, - &format!("builtin traits can only be \ - implemented on structs or enums")[]); + span_err!(self.tcx.sess, item.span, E0209, + "builtin traits can only be \ + implemented on structs or enums"); } } } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 350cee99f6a..7d59c3f9d3f 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -490,24 +490,21 @@ fn check_implementations_of_copy(&self) { match ty::can_type_implement_copy(¶m_env, span, self_type) { Ok(()) => {} Err(ty::FieldDoesNotImplementCopy(name)) => { - tcx.sess - .span_err(span, - &format!("the trait `Copy` may not be \ + span_err!(tcx.sess, span, E0204, + "the trait `Copy` may not be \ implemented for this type; field \ `{}` does not implement `Copy`", - token::get_name(name))[]) + token::get_name(name)) } Err(ty::VariantDoesNotImplementCopy(name)) => { - tcx.sess - .span_err(span, - &format!("the trait `Copy` may not be \ + span_err!(tcx.sess, span, E0205, + "the trait `Copy` may not be \ implemented for this type; variant \ `{}` does not implement `Copy`", - token::get_name(name))[]) + token::get_name(name)) } Err(ty::TypeIsStructural) => { - tcx.sess - .span_err(span, + span_err!(tcx.sess, span, E0206, "the trait `Copy` may not be implemented \ for this type; type is not a structure or \ enumeration") diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 77d71e740d6..60b1fa5f4cf 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -89,13 +89,11 @@ fn visit_item(&mut self, item: &'v ast::Item) { } Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => { if !ty::has_attr(self.tcx, trait_def_id, "old_orphan_check") { - self.tcx.sess.span_err( - item.span, - format!( + span_err!(self.tcx.sess, item.span, E0210, "type parameter `{}` is not constrained by any local type; \ only traits defined in the current crate can be implemented \ for a type parameter", - param_ty.user_string(self.tcx)).as_slice()); + param_ty.user_string(self.tcx)); self.tcx.sess.span_note( item.span, format!("for a limited time, you can add \ diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index ce7ba9ac11e..a7bad3dc789 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -65,7 +65,7 @@ fn check_for_overlapping_impls_of_trait(&self, continue; } - for &impl2_def_id in trait_impls.slice_from(i+1).iter() { + for &impl2_def_id in trait_impls[(i+1)..].iter() { self.check_if_impls_overlap(trait_def_id, impl1_def_id, impl2_def_id); diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index e30d0a29938..867dea95885 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -37,8 +37,7 @@ fn visit_item(&mut self, item: &'v ast::Item) { match unsafety { ast::Unsafety::Normal => { /* OK */ } ast::Unsafety::Unsafe => { - self.tcx.sess.span_err( - item.span, + span_err!(self.tcx.sess, item.span, E0197, "inherent impls cannot be declared as unsafe"); } } @@ -49,24 +48,21 @@ fn visit_item(&mut self, item: &'v ast::Item) { match (trait_def.unsafety, unsafety, polarity) { (ast::Unsafety::Unsafe, ast::Unsafety::Unsafe, ast::ImplPolarity::Negative) => { - self.tcx.sess.span_err( - item.span, - format!("negative implementations are not unsafe").as_slice()); + span_err!(self.tcx.sess, item.span, E0198, + "negative implementations are not unsafe"); } (ast::Unsafety::Normal, ast::Unsafety::Unsafe, _) => { - self.tcx.sess.span_err( - item.span, - format!("implementing the trait `{}` is not unsafe", - trait_ref.user_string(self.tcx)).as_slice()); + span_err!(self.tcx.sess, item.span, E0199, + "implementing the trait `{}` is not unsafe", + trait_ref.user_string(self.tcx)); } (ast::Unsafety::Unsafe, ast::Unsafety::Normal, ast::ImplPolarity::Positive) => { - self.tcx.sess.span_err( - item.span, - format!("the trait `{}` requires an `unsafe impl` declaration", - trait_ref.user_string(self.tcx)).as_slice()); + span_err!(self.tcx.sess, item.span, E0200, + "the trait `{}` requires an `unsafe impl` declaration", + trait_ref.user_string(self.tcx)); } (ast::Unsafety::Unsafe, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 80c0a72db83..8158b8da86d 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -452,7 +452,7 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CollectCtxt<'a, 'tcx>, let mut seen_methods = FnvHashSet(); for m in ms { if !seen_methods.insert(m.pe_ident().repr(tcx)) { - tcx.sess.span_err(m.span, "duplicate method in trait impl"); + span_err!(tcx.sess, m.span, E0201, "duplicate method in trait impl"); } let m_def_id = local_def(m.id); @@ -555,6 +555,7 @@ fn convert(ccx: &CollectCtxt, it: &ast::Item) { debug!("convert: item {} with id {}", token::get_ident(it.ident), it.id); match it.node { // These don't define types. + ast::ItemExternCrate(_) | ast::ItemUse(_) | ast::ItemForeignMod(_) | ast::ItemMod(_) | ast::ItemMac(_) => {} ast::ItemEnum(ref enum_definition, ref generics) => { let scheme = ty_of_item(ccx, it); @@ -608,7 +609,7 @@ fn convert(ccx: &CollectCtxt, it: &ast::Item) { } ast::TypeImplItem(ref typedef) => { if opt_trait_ref.is_none() { - tcx.sess.span_err(typedef.span, + span_err!(tcx.sess, typedef.span, E0202, "associated items are not allowed in inherent impls"); } @@ -1004,6 +1005,7 @@ fn ty_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, it: &ast::Item) tcx.tcache.borrow_mut().insert(local_def(it.id), scheme.clone()); return scheme; } + ast::ItemExternCrate(_) | ast::ItemUse(_) | ast::ItemImpl(..) | ast::ItemMod(_) | ast::ItemForeignMod(_) | ast::ItemMac(_) => panic!(), } @@ -1160,7 +1162,8 @@ fn add_unsized_bound<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, assert!(ptr.bound_lifetimes.is_empty()); unbound = Some(ptr.trait_ref.clone()); } else { - ccx.tcx.sess.span_err(span, "type parameter has more than one relaxed default \ + span_err!(ccx.tcx.sess, span, E0203, + "type parameter has more than one relaxed default \ bound, only one is supported"); } } @@ -1690,11 +1693,10 @@ fn enforce_impl_ty_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>, impl trait, self type, or predicates", param_ty.user_string(tcx)).as_slice()); } else { - tcx.sess.span_err( - ty_param.span, - format!("the type parameter `{}` is not constrained by the \ + span_err!(tcx.sess, ty_param.span, E0207, + "the type parameter `{}` is not constrained by the \ impl trait, self type, or predicates", - param_ty.user_string(tcx)).as_slice()); + param_ty.user_string(tcx)); tcx.sess.span_help( ty_param.span, format!("you can temporarily opt out of this rule by placing \ diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index c9e15b93ad4..3627fa41160 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -10,38 +10,7 @@ #![allow(non_snake_case)] -register_diagnostic! { - E0001, -r##" - This error suggests that the expression arm corresponding to the noted pattern - will never be reached as for all possible values of the expression being matched, - one of the preceeding patterns will match. - - This means that perhaps some of the preceeding patterns are too general, this - one is too specific or the ordering is incorrect. -"## } - register_diagnostics! { - E0002, - E0003, - E0004, - E0005, - E0006, - E0007, - E0008, - E0009, - E0010, - E0011, - E0012, - E0013, - E0014, - E0015, - E0016, - E0017, - E0018, - E0019, - E0020, - E0022, E0023, E0024, E0025, @@ -61,12 +30,9 @@ E0046, E0049, E0050, - E0051, - E0052, E0053, E0054, E0055, - E0056, E0057, E0059, E0060, @@ -101,16 +67,12 @@ E0092, E0093, E0094, - E0100, E0101, E0102, E0103, E0104, E0106, E0107, - E0108, - E0109, - E0110, E0116, E0117, E0118, @@ -125,38 +87,92 @@ E0130, E0131, E0132, - E0133, - E0134, - E0135, - E0136, - E0137, - E0138, - E0139, - E0140, E0141, - E0152, - E0153, - E0157, - E0158, E0159, - E0161, - E0162, E0163, E0164, - E0165, E0166, E0167, E0168, - E0169, - E0171, E0172, E0173, // manual implementations of unboxed closure traits are experimental E0174, // explicit use of unboxed closure methods are experimental - E0177, E0178, - E0180, - E0181, E0182, E0183, - E0184 + E0184, + E0185, + E0186, + E0187, // can't infer the kind of the closure + E0188, // types differ in mutability + E0189, // can only cast a boxed pointer to a boxed object + E0190, // can only cast a &-pointer to an &-object + E0191, // value of the associated type must be specified + E0192, // negative imples are allowed just fo `Send` and `Sync` + E0193, // cannot bound type where clause bounds may only be attached to types + // involving type parameters + E0194, + E0195, // lifetime parameters or bounds on method do not match the trait declaration + E0196, // cannot determine a type for this unboxed closure + E0197, // inherent impls cannot be declared as unsafe + E0198, // negative implementations are not unsafe + E0199, // implementing trait is not unsafe + E0200, // trait requires an `unsafe impl` declaration + E0201, // duplicate method in trait impl + E0202, // associated items are not allowed in inherint impls + E0203, // type parameter has more than one relaxed default bound, + // and only one is supported + E0204, // trait `Copy` may not be implemented for this type; field + // does not implement `Copy` + E0205, // trait `Copy` may not be implemented for this type; variant + // does not implement `copy` + E0206, // trait `Copy` may not be implemented for this type; type is + // not a structure or enumeration + E0207, // type parameter is not constrained by the impl trait, self type, or predicate + E0208, + E0209, // builtin traits can only be implemented on structs or enums + E0210, // type parameter is not constrained by any local type + E0211, + E0212, // cannot extract an associated type from a higher-ranked trait bound + E0213, // associated types are not accepted in this context + E0214, // parenthesized parameters may only be used with a trait + E0215, // angle-bracket notation is not stable with `Fn` + E0216, // parenthetical notation is only stable with `Fn` + E0217, // ambiguous associated type, defined in multiple supertraits + E0218, // no associated type defined + E0219, // associated type defined in higher-ranked supertrait + E0220, // associated type not found for type parameter + E0221, // ambiguous associated type in bounds + E0222, // variadic function must have C calling convention + E0223, // ambiguous associated type + E0224, // at least one non-builtin train is required for an object type + E0225, // only the builtin traits can be used as closure or object bounds + E0226, // only a single explicit lifetime bound is permitted + E0227, // ambiguous lifetime bound, explicit lifetime bound required + E0228, // explicit lifetime bound required + E0229, // associated type bindings are not allowed here + E0230, // there is no type parameter on trait + E0231, // only named substitution parameters are allowed + E0232, // this attribute must have a value + E0233, + E0234, // `for` loop expression has type which does not implement the `Iterator` trait + E0235, // structure constructor specifies a structure of type but + E0236, // no lang item for range syntax + E0237, // no lang item for range syntax + E0238, // parenthesized parameters may only be used with a trait + E0239, // `next` method of `Iterator` trait has unexpected type + E0240, + E0241, + E0242, // internal error looking up a definition + E0243, // wrong number of type arguments + E0244, // wrong number of type arguments + E0245, // not a trait + E0246, // illegal recursive type + E0247, // found module name used as a type + E0248, // found value name used as a type + E0249, // expected constant expr for array length + E0250 // expected constant expr for array length } + +__build_diagnostic_array! { DIAGNOSTICS } + diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 47b5cd4b11e..78007f3552e 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -111,6 +111,10 @@ use std::cell::RefCell; +// NB: This module needs to be declared first so diagnostics are +// registered before they are used. +pub mod diagnostics; + mod check; mod rscope; mod astconv; @@ -158,7 +162,7 @@ fn lookup_def_tcx(tcx:&ty::ctxt, sp: Span, id: ast::NodeId) -> def::Def { match tcx.def_map.borrow().get(&id) { Some(x) => x.clone(), _ => { - tcx.sess.span_fatal(sp, "internal error looking up a definition") + span_fatal!(tcx.sess, sp, E0242, "internal error looking up a definition") } } } @@ -202,11 +206,11 @@ fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>, match result { Ok(_) => true, Err(ref terr) => { - tcx.sess.span_err(span, - &format!("{}: {}", + span_err!(tcx.sess, span, E0211, + "{}: {}", msg(), ty::type_err_to_str(tcx, - terr))[]); + terr)); ty::note_and_explain_type_err(tcx, terr); false } diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index 86447e76a89..6ed18368738 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -240,7 +240,7 @@ enum VarianceTerm<'a> { InferredTerm(InferredIndex), } -impl<'a> fmt::Show for VarianceTerm<'a> { +impl<'a> fmt::Debug for VarianceTerm<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { ConstantTerm(c1) => write!(f, "{:?}", c1), @@ -380,6 +380,8 @@ fn visit_item(&mut self, item: &ast::Item) { visit::walk_item(self, item); } + ast::ItemExternCrate(_) | + ast::ItemUse(_) | ast::ItemImpl(..) | ast::ItemStatic(..) | ast::ItemConst(..) | @@ -532,6 +534,8 @@ fn visit_item(&mut self, item: &ast::Item) { } } + ast::ItemExternCrate(_) | + ast::ItemUse(_) | ast::ItemStatic(..) | ast::ItemConst(..) | ast::ItemFn(..) | @@ -1055,7 +1059,7 @@ fn write(&self) { // attribute and report an error with various results if found. if ty::has_attr(tcx, item_def_id, "rustc_variance") { let found = item_variances.repr(tcx); - tcx.sess.span_err(tcx.map.span(item_id), &found[]); + span_err!(tcx.sess, tcx.map.span(item_id), E0208, "{}", &found[]); } let newly_added = tcx.item_variance_map.borrow_mut() diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index ccaefadc1fc..6e79bd9bebd 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -147,14 +147,22 @@ pub fn record_extern_fqn(cx: &DocContext, did: ast::DefId, kind: clean::TypeKind pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Trait { + use clean::TraitMethod; + let def = ty::lookup_trait_def(tcx, did); let trait_items = ty::trait_items(tcx, did).clean(cx); let provided = ty::provided_trait_methods(tcx, did); let items = trait_items.into_iter().map(|trait_item| { - if provided.iter().any(|a| a.def_id == trait_item.def_id) { - clean::ProvidedMethod(trait_item) - } else { - clean::RequiredMethod(trait_item) + match trait_item.inner { + clean::TyMethodItem(_) => { + if provided.iter().any(|a| a.def_id == trait_item.def_id) { + TraitMethod::ProvidedMethod(trait_item) + } else { + TraitMethod::RequiredMethod(trait_item) + } + }, + clean::AssociatedTypeItem(_) => TraitMethod::TypeTraitItem(trait_item), + _ => unreachable!() } }); let trait_def = ty::lookup_trait_def(tcx, did); @@ -311,12 +319,25 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt, }; Some(item) } - ty::TypeTraitItem(_) => { - // FIXME(pcwalton): Implement. - None + ty::TypeTraitItem(ref assoc_ty) => { + let did = assoc_ty.def_id; + let type_scheme = ty::lookup_item_type(tcx, did); + // Not sure the choice of ParamSpace actually matters here, because an + // associated type won't have generics on the LHS + let typedef = (type_scheme, subst::ParamSpace::TypeSpace).clean(cx); + Some(clean::Item { + name: Some(assoc_ty.name.clean(cx)), + inner: clean::TypedefItem(typedef), + source: clean::Span::empty(), + attrs: vec![], + visibility: None, + stability: stability::lookup(tcx, did).clean(cx), + def_id: did + }) } } }).collect(); + let polarity = csearch::get_impl_polarity(tcx, did); return Some(clean::Item { inner: clean::ImplItem(clean::Impl { derived: clean::detect_derived(attrs.as_slice()), @@ -329,6 +350,7 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt, for_: ty.ty.clean(cx), generics: (&ty.generics, subst::TypeSpace).clean(cx), items: trait_items, + polarity: polarity.map(|p| { p.clean(cx) }), }), source: clean::Span::empty(), name: None, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7342c9f3e81..203d9758c57 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -18,8 +18,7 @@ pub use self::StructField::*; pub use self::VariantKind::*; pub use self::Mutability::*; -pub use self::ViewItemInner::*; -pub use self::ViewPath::*; +pub use self::Import::*; pub use self::ItemEnum::*; pub use self::Attribute::*; pub use self::TyParamBound::*; @@ -45,7 +44,6 @@ use rustc::middle::subst::{self, ParamSpace, VecPerParamSpace}; use rustc::middle::ty; use rustc::middle::stability; -use rustc::session::config; use std::rc::Rc; use std::u32; @@ -116,7 +114,7 @@ fn clean(&self, cx: &DocContext) -> Vec { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Crate { pub name: String, pub src: FsPath, @@ -127,6 +125,8 @@ pub struct Crate { impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { fn clean(&self, cx: &DocContext) -> Crate { + use rustc::session::config::Input; + let mut externs = Vec::new(); cx.sess().cstore.iter_crate_data(|n, meta| { externs.push((n, meta.clean(cx))); @@ -134,8 +134,8 @@ fn clean(&self, cx: &DocContext) -> Crate { externs.sort_by(|&(a, _), &(b, _)| a.cmp(&b)); // Figure out the name of this crate - let input = config::Input::File(cx.src.clone()); - let name = link::find_crate_name(None, self.attrs.as_slice(), &input); + let input = &cx.input; + let name = link::find_crate_name(None, self.attrs.as_slice(), input); // Clean the crate, translating the entire libsyntax AST to one that is // understood by rustdoc. @@ -188,9 +188,14 @@ fn clean(&self, cx: &DocContext) -> Crate { m.items.extend(tmp.into_iter()); } + let src = match cx.input { + Input::File(ref path) => path.clone(), + Input::Str(_) => FsPath::new("") // FIXME: this is wrong + }; + Crate { name: name.to_string(), - src: cx.src.clone(), + src: src, module: Some(module), externs: externs, primitives: primitives, @@ -198,7 +203,7 @@ fn clean(&self, cx: &DocContext) -> Crate { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct ExternalCrate { pub name: String, pub attrs: Vec, @@ -231,7 +236,7 @@ fn clean(&self, cx: &DocContext) -> ExternalCrate { /// Anything with a source location and set of attributes and, optionally, a /// name. That is, anything that can be documented. This doesn't correspond /// directly to the AST's concept of an item; it's a strict superset. -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Item { /// Stringified span pub source: Span, @@ -307,8 +312,10 @@ pub fn is_fn(&self) -> bool { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum ItemEnum { + ExternCrateItem(String, Option), + ImportItem(Import), StructItem(Struct), EnumItem(Enum), FunctionItem(Function), @@ -318,8 +325,6 @@ pub enum ItemEnum { ConstantItem(Constant), TraitItem(Trait), ImplItem(Impl), - /// `use` and `extern crate` - ViewItemItem(ViewItem), /// A method signature only. Used for required methods in traits (ie, /// non-default-methods). TyMethodItem(TyMethod), @@ -336,7 +341,7 @@ pub enum ItemEnum { AssociatedTypeItem(TyParam), } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Module { pub items: Vec, pub is_crate: bool, @@ -349,27 +354,21 @@ fn clean(&self, cx: &DocContext) -> Item { } else { "".to_string() }; - let mut foreigns = Vec::new(); - for subforeigns in self.foreigns.clean(cx).into_iter() { - for foreign in subforeigns.into_iter() { - foreigns.push(foreign) - } - } - let items: Vec > = vec!( - self.structs.clean(cx), - self.enums.clean(cx), - self.fns.clean(cx), - foreigns, - self.mods.clean(cx), - self.typedefs.clean(cx), - self.statics.clean(cx), - self.constants.clean(cx), - self.traits.clean(cx), - self.impls.clean(cx), - self.view_items.clean(cx).into_iter() - .flat_map(|s| s.into_iter()).collect(), - self.macros.clean(cx), - ); + let items: Vec = + self.extern_crates.iter().map(|x| x.clean(cx)) + .chain(self.imports.iter().flat_map(|x| x.clean(cx).into_iter())) + .chain(self.structs.iter().map(|x| x.clean(cx))) + .chain(self.enums.iter().map(|x| x.clean(cx))) + .chain(self.fns.iter().map(|x| x.clean(cx))) + .chain(self.foreigns.iter().flat_map(|x| x.clean(cx).into_iter())) + .chain(self.mods.iter().map(|x| x.clean(cx))) + .chain(self.typedefs.iter().map(|x| x.clean(cx))) + .chain(self.statics.iter().map(|x| x.clean(cx))) + .chain(self.constants.iter().map(|x| x.clean(cx))) + .chain(self.traits.iter().map(|x| x.clean(cx))) + .chain(self.impls.iter().map(|x| x.clean(cx))) + .chain(self.macros.iter().map(|x| x.clean(cx))) + .collect(); // determine if we should display the inner contents or // the outer `mod` item for the source code. @@ -395,9 +394,7 @@ fn clean(&self, cx: &DocContext) -> Item { def_id: ast_util::local_def(self.id), inner: ModuleItem(Module { is_crate: self.is_crate, - items: items.iter() - .flat_map(|x| x.iter().map(|x| (*x).clone())) - .collect(), + items: items }) } } @@ -938,7 +935,7 @@ fn has_sized_bound(bounds: &[TyParamBound], cx: &DocContext) -> bool { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Method { pub generics: Generics, pub self_: SelfTy, @@ -977,7 +974,7 @@ fn clean(&self, cx: &DocContext) -> Item { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct TyMethod { pub unsafety: ast::Unsafety, pub decl: FnDecl, @@ -1015,7 +1012,7 @@ fn clean(&self, cx: &DocContext) -> Item { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq)] +#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Show)] pub enum SelfTy { SelfStatic, SelfValue, @@ -1036,7 +1033,7 @@ fn clean(&self, cx: &DocContext) -> SelfTy { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Function { pub decl: FnDecl, pub generics: Generics, @@ -1155,7 +1152,7 @@ fn clean(&self, cx: &DocContext) -> FunctionRetTy { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Trait { pub unsafety: ast::Unsafety, pub items: Vec, @@ -1199,11 +1196,11 @@ fn clean(&self, cx: &DocContext) -> PolyTrait { /// An item belonging to a trait, whether a method or associated. Could be named /// TraitItem except that's already taken by an exported enum variant. -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum TraitMethod { RequiredMethod(Item), ProvidedMethod(Item), - TypeTraitItem(Item), + TypeTraitItem(Item), // an associated type } impl TraitMethod { @@ -1244,7 +1241,7 @@ fn clean(&self, cx: &DocContext) -> TraitMethod { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum ImplMethod { MethodImplItem(Item), TypeImplItem(Item), @@ -1380,7 +1377,7 @@ pub enum PrimitiveType { PrimitiveTuple, } -#[derive(Clone, RustcEncodable, RustcDecodable, Copy)] +#[derive(Clone, RustcEncodable, RustcDecodable, Copy, Show)] pub enum TypeKind { TypeEnum, TypeFunction, @@ -1623,7 +1620,7 @@ fn clean(&self, cx: &DocContext) -> Type { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum StructField { HiddenStructField, // inserted later by strip passes TypedStructField(Type), @@ -1682,7 +1679,7 @@ fn clean(&self, _: &DocContext) -> Option { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Struct { pub struct_type: doctree::StructType, pub generics: Generics, @@ -1712,7 +1709,7 @@ fn clean(&self, cx: &DocContext) -> Item { /// This is a more limited form of the standard Struct, different in that /// it lacks the things most items have (name, id, parameterization). Found /// only as a variant in an enum. -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct VariantStruct { pub struct_type: doctree::StructType, pub fields: Vec, @@ -1729,7 +1726,7 @@ fn clean(&self, cx: &DocContext) -> VariantStruct { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Enum { pub variants: Vec, pub generics: Generics, @@ -1754,7 +1751,7 @@ fn clean(&self, cx: &DocContext) -> Item { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Variant { pub kind: VariantKind, } @@ -1822,7 +1819,7 @@ fn clean(&self, cx: &DocContext) -> Item { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum VariantKind { CLikeVariant, TupleVariant(Vec), @@ -1872,9 +1869,9 @@ fn clean(&self, cx: &DocContext) -> Span { Span { filename: filename.to_string(), loline: lo.line, - locol: lo.col.to_uint(), + locol: lo.col.to_usize(), hiline: hi.line, - hicol: hi.col.to_uint(), + hicol: hi.col.to_usize(), } } } @@ -1969,7 +1966,7 @@ fn clean(&self, _: &DocContext) -> String { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Typedef { pub type_: Type, pub generics: Generics, @@ -2082,13 +2079,29 @@ fn clean(&self, _: &DocContext) -> Mutability { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Copy, Show)] +pub enum ImplPolarity { + Positive, + Negative, +} + +impl Clean for ast::ImplPolarity { + fn clean(&self, _: &DocContext) -> ImplPolarity { + match self { + &ast::ImplPolarity::Positive => ImplPolarity::Positive, + &ast::ImplPolarity::Negative => ImplPolarity::Negative, + } + } +} + +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Impl { pub generics: Generics, pub trait_: Option, pub for_: Type, pub items: Vec, pub derived: bool, + pub polarity: Option, } fn detect_derived(attrs: &[M]) -> bool { @@ -2115,17 +2128,27 @@ fn clean(&self, cx: &DocContext) -> Item { } }).collect(), derived: detect_derived(self.attrs.as_slice()), + polarity: Some(self.polarity.clean(cx)), }), } } } -#[derive(Clone, RustcEncodable, RustcDecodable)] -pub struct ViewItem { - pub inner: ViewItemInner, +impl Clean for doctree::ExternCrate { + fn clean(&self, cx: &DocContext) -> Item { + Item { + name: None, + attrs: self.attrs.clean(cx), + source: self.whence.clean(cx), + def_id: ast_util::local_def(0), + visibility: self.vis.clean(cx), + stability: None, + inner: ExternCrateItem(self.name.clean(cx), self.path.clone()) + } + } } -impl Clean> for ast::ViewItem { +impl Clean> for doctree::Import { fn clean(&self, cx: &DocContext) -> Vec { // We consider inlining the documentation of `pub use` statements, but we // forcefully don't inline if this is not public or if the @@ -2136,81 +2159,63 @@ fn clean(&self, cx: &DocContext) -> Vec { None => false, } }); - let convert = |&: node: &ast::ViewItem_| { - Item { - name: None, - attrs: self.attrs.clean(cx), - source: self.span.clean(cx), - def_id: ast_util::local_def(0), - visibility: self.vis.clean(cx), - stability: None, - inner: ViewItemItem(ViewItem { inner: node.clean(cx) }), + let (mut ret, inner) = match self.node { + ast::ViewPathGlob(ref p) => { + (vec![], GlobImport(resolve_use_source(cx, p.clean(cx), self.id))) } - }; - let mut ret = Vec::new(); - match self.node { - ast::ViewItemUse(ref path) if !denied => { - match path.node { - ast::ViewPathGlob(..) => ret.push(convert(&self.node)), - ast::ViewPathList(ref a, ref list, ref b) => { - // Attempt to inline all reexported items, but be sure - // to keep any non-inlineable reexports so they can be - // listed in the documentation. - let remaining = list.iter().filter(|path| { - match inline::try_inline(cx, path.node.id(), None) { - Some(items) => { - ret.extend(items.into_iter()); false - } - None => true, + ast::ViewPathList(ref p, ref list) => { + // Attempt to inline all reexported items, but be sure + // to keep any non-inlineable reexports so they can be + // listed in the documentation. + let mut ret = vec![]; + let remaining = if !denied { + let mut remaining = vec![]; + for path in list.iter() { + match inline::try_inline(cx, path.node.id(), None) { + Some(items) => { + ret.extend(items.into_iter()); + } + None => { + remaining.push(path.clean(cx)); } - }).map(|a| a.clone()).collect::>(); - if remaining.len() > 0 { - let path = ast::ViewPathList(a.clone(), - remaining, - b.clone()); - let path = syntax::codemap::dummy_spanned(path); - ret.push(convert(&ast::ViewItemUse(P(path)))); } } - ast::ViewPathSimple(ident, _, id) => { - match inline::try_inline(cx, id, Some(ident)) { - Some(items) => ret.extend(items.into_iter()), - None => ret.push(convert(&self.node)), - } + remaining + } else { + list.clean(cx) + }; + if remaining.is_empty() { + return ret; + } + (ret, ImportList(resolve_use_source(cx, p.clean(cx), self.id), + remaining)) + } + ast::ViewPathSimple(i, ref p) => { + if !denied { + match inline::try_inline(cx, self.id, Some(i)) { + Some(items) => return items, + None => {} } } + (vec![], SimpleImport(i.clean(cx), + resolve_use_source(cx, p.clean(cx), self.id))) } - ref n => ret.push(convert(n)), - } - return ret; + }; + ret.push(Item { + name: None, + attrs: self.attrs.clean(cx), + source: self.whence.clean(cx), + def_id: ast_util::local_def(0), + visibility: self.vis.clean(cx), + stability: None, + inner: ImportItem(inner) + }); + ret } } -#[derive(Clone, RustcEncodable, RustcDecodable)] -pub enum ViewItemInner { - ExternCrate(String, Option, ast::NodeId), - Import(ViewPath) -} - -impl Clean for ast::ViewItem_ { - fn clean(&self, cx: &DocContext) -> ViewItemInner { - match self { - &ast::ViewItemExternCrate(ref i, ref p, ref id) => { - let string = match *p { - None => None, - Some((ref x, _)) => Some(x.get().to_string()), - }; - ExternCrate(i.clean(cx), string, *id) - } - &ast::ViewItemUse(ref vp) => { - Import(vp.clean(cx)) - } - } - } -} - -#[derive(Clone, RustcEncodable, RustcDecodable)] -pub enum ViewPath { +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] +pub enum Import { // use source as str; SimpleImport(String, ImportSource), // use source::*; @@ -2219,28 +2224,13 @@ pub enum ViewPath { ImportList(ImportSource, Vec), } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct ImportSource { pub path: Path, pub did: Option, } -impl Clean for ast::ViewPath { - fn clean(&self, cx: &DocContext) -> ViewPath { - match self.node { - ast::ViewPathSimple(ref i, ref p, id) => - SimpleImport(i.clean(cx), resolve_use_source(cx, p.clean(cx), id)), - ast::ViewPathGlob(ref p, id) => - GlobImport(resolve_use_source(cx, p.clean(cx), id)), - ast::ViewPathList(ref p, ref pl, id) => { - ImportList(resolve_use_source(cx, p.clean(cx), id), - pl.clean(cx)) - } - } - } -} - -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct ViewListIdent { pub name: String, pub source: Option, @@ -2459,7 +2449,7 @@ fn resolve_def(cx: &DocContext, id: ast::NodeId) -> Option { }) } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Macro { pub source: String, } @@ -2480,7 +2470,7 @@ fn clean(&self, cx: &DocContext) -> Item { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Stability { pub level: attr::StabilityLevel, pub text: String @@ -2516,14 +2506,14 @@ fn clean(&self, cx: &DocContext) -> Item { source: DUMMY_SP.clean(cx), name: Some(self.name.clean(cx)), attrs: Vec::new(), - // FIXME(#18048): this is wrong, but cross-crate associated types are broken - // anyway, for the time being. inner: AssociatedTypeItem(TyParam { name: self.name.clean(cx), did: ast::DefId { krate: 0, node: ast::DUMMY_NODE_ID }, + // FIXME(#20727): bounds are missing and need to be filled in from the + // predicates on the trait itself bounds: vec![], default: None, }), @@ -2555,6 +2545,16 @@ fn clean(&self, cx: &DocContext) -> Item { } } +impl<'a> Clean for (ty::TypeScheme<'a>, ParamSpace) { + fn clean(&self, cx: &DocContext) -> Typedef { + let (ref ty_scheme, ps) = *self; + Typedef { + type_: ty_scheme.ty.clean(cx), + generics: (&ty_scheme.generics, ps).clean(cx) + } + } +} + fn lang_struct(cx: &DocContext, did: Option, t: ty::Ty, name: &str, fallback: fn(Box) -> Type) -> Type { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5bef0195874..04947e41663 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -12,7 +12,6 @@ use rustc_driver::driver; use rustc::session::{self, config}; use rustc::session::config::UnstableFeatures; -use rustc::session::search_paths::SearchPaths; use rustc::middle::{privacy, ty}; use rustc::lint; use rustc_trans::back::link; @@ -27,6 +26,9 @@ use clean; use clean::Clean; +pub use rustc::session::config::Input; +pub use rustc::session::search_paths::SearchPaths; + /// Are we generating documentation (`Typed`) or tests (`NotTyped`)? pub enum MaybeTyped<'tcx> { Typed(ty::ctxt<'tcx>), @@ -39,7 +41,7 @@ pub enum MaybeTyped<'tcx> { pub struct DocContext<'tcx> { pub krate: &'tcx ast::Crate, pub maybe_typed: MaybeTyped<'tcx>, - pub src: Path, + pub input: Input, pub external_paths: ExternalPaths, pub external_traits: RefCell>>, pub external_typarams: RefCell>>, @@ -80,12 +82,15 @@ pub struct CrateAnalysis { pub type Externs = HashMap>; pub fn run_core(search_paths: SearchPaths, cfgs: Vec, externs: Externs, - cpath: &Path, triple: Option) + input: Input, triple: Option) -> (clean::Crate, CrateAnalysis) { // Parse, resolve, and typecheck the given crate. - let input = config::Input::File(cpath.clone()); + let cpath = match input { + Input::File(ref p) => Some(p.clone()), + _ => None + }; let warning_lint = lint::builtin::WARNINGS.name_lower(); @@ -107,8 +112,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec, externs: Externs, let span_diagnostic_handler = diagnostic::mk_span_handler(diagnostic_handler, codemap); - let sess = session::build_session_(sessopts, - Some(cpath.clone()), + let sess = session::build_session_(sessopts, cpath, span_diagnostic_handler); let cfg = config::build_configuration(&sess); @@ -136,7 +140,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec, externs: Externs, let ctxt = DocContext { krate: ty_cx.map.krate(), maybe_typed: Typed(ty_cx), - src: cpath.clone(), + input: input, external_traits: RefCell::new(Some(HashMap::new())), external_typarams: RefCell::new(Some(HashMap::new())), external_paths: RefCell::new(Some(HashMap::new())), diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 99afef4173f..0e8ab594c20 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -25,6 +25,8 @@ pub struct Module { pub attrs: Vec, pub where_outer: Span, pub where_inner: Span, + pub extern_crates: Vec, + pub imports: Vec, pub structs: Vec, pub enums: Vec, pub fns: Vec, @@ -38,7 +40,6 @@ pub struct Module { pub stab: Option, pub impls: Vec, pub foreigns: Vec, - pub view_items: Vec, pub macros: Vec, pub is_crate: bool, } @@ -53,6 +54,8 @@ pub fn new(name: Option) -> Module { where_outer: syntax::codemap::DUMMY_SP, where_inner: syntax::codemap::DUMMY_SP, attrs : Vec::new(), + extern_crates: Vec::new(), + imports : Vec::new(), structs : Vec::new(), enums : Vec::new(), fns : Vec::new(), @@ -62,7 +65,6 @@ pub fn new(name: Option) -> Module { constants : Vec::new(), traits : Vec::new(), impls : Vec::new(), - view_items : Vec::new(), foreigns : Vec::new(), macros : Vec::new(), is_crate : false, @@ -202,6 +204,22 @@ pub struct Macro { pub stab: Option, } +pub struct ExternCrate { + pub name: Ident, + pub path: Option, + pub vis: ast::Visibility, + pub attrs: Vec, + pub whence: Span, +} + +pub struct Import { + pub id: NodeId, + pub vis: ast::Visibility, + pub attrs: Vec, + pub node: ast::ViewPath_, + pub whence: Span, +} + pub fn struct_type_from_def(sd: &ast::StructDef) -> StructType { if sd.ctor_id.is_some() { // We are in a tuple-struct diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs index 6fb78d9a833..fe8ac3fde5f 100644 --- a/src/librustdoc/html/escape.rs +++ b/src/librustdoc/html/escape.rs @@ -19,7 +19,7 @@ /// string when passed to a format string. pub struct Escape<'a>(pub &'a str); -impl<'a> fmt::String for Escape<'a> { +impl<'a> fmt::Display for Escape<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { // Because the internet is always right, turns out there's not that many // characters to escape: http://stackoverflow.com/questions/7381974 @@ -29,7 +29,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { for (i, ch) in s.bytes().enumerate() { match ch as char { '<' | '>' | '&' | '\'' | '"' => { - try!(fmt.write_str(pile_o_bits.slice(last, i))); + try!(fmt.write_str(&pile_o_bits[last.. i])); let s = match ch as char { '>' => ">", '<' => "<", @@ -46,7 +46,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { } if last < s.len() { - try!(fmt.write_str(pile_o_bits.slice_from(last))); + try!(fmt.write_str(&pile_o_bits[last..])); } Ok(()) } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 57b8d666c95..b713032bc05 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -66,7 +66,7 @@ pub fn get(&self) -> ast::Unsafety { } } -impl<'a, T: fmt::String> fmt::String for CommaSep<'a, T> { +impl<'a, T: fmt::Display> fmt::Display for CommaSep<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for (i, item) in self.0.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -76,7 +76,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl<'a> fmt::String for TyParamBounds<'a> { +impl<'a> fmt::Display for TyParamBounds<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let &TyParamBounds(bounds) = self; for (i, bound) in bounds.iter().enumerate() { @@ -89,7 +89,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for clean::Generics { +impl fmt::Display for clean::Generics { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.lifetimes.len() == 0 && self.type_params.len() == 0 { return Ok(()) } try!(f.write_str("<")); @@ -126,7 +126,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl<'a> fmt::String for WhereClause<'a> { +impl<'a> fmt::Display for WhereClause<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let &WhereClause(gens) = self; if gens.where_predicates.len() == 0 { @@ -163,14 +163,14 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for clean::Lifetime { +impl fmt::Display for clean::Lifetime { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(f.write_str(self.get_ref())); Ok(()) } } -impl fmt::String for clean::PolyTrait { +impl fmt::Display for clean::PolyTrait { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.lifetimes.len() > 0 { try!(f.write_str("for<")); @@ -186,7 +186,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for clean::TyParamBound { +impl fmt::Display for clean::TyParamBound { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { clean::RegionBound(ref lt) => { @@ -203,7 +203,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for clean::PathParameters { +impl fmt::Display for clean::PathParameters { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { clean::PathParameters::AngleBracketed { @@ -257,14 +257,14 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for clean::PathSegment { +impl fmt::Display for clean::PathSegment { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(f.write_str(self.name.as_slice())); write!(f, "{}", self.params) } } -impl fmt::String for clean::Path { +impl fmt::Display for clean::Path { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.global { try!(f.write_str("::")) @@ -358,7 +358,7 @@ fn path(w: &mut fmt::Formatter, // This is a documented path, link to it! Some((ref fqp, shortty)) if abs_root.is_some() => { let mut url = String::from_str(abs_root.unwrap().as_slice()); - let to_link = &fqp[..(fqp.len() - 1)]; + let to_link = &fqp[..fqp.len() - 1]; for component in to_link.iter() { url.push_str(component.as_slice()); url.push_str("/"); @@ -450,7 +450,7 @@ fn tybounds(w: &mut fmt::Formatter, } } -impl fmt::String for clean::Type { +impl fmt::Display for clean::Type { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { clean::TyParamBinder(id) => { @@ -539,7 +539,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for clean::Arguments { +impl fmt::Display for clean::Arguments { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for (i, input) in self.values.iter().enumerate() { if i > 0 { try!(write!(f, ", ")); } @@ -552,7 +552,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for clean::FunctionRetTy { +impl fmt::Display for clean::FunctionRetTy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { clean::Return(clean::Tuple(ref tys)) if tys.is_empty() => Ok(()), @@ -563,13 +563,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for clean::FnDecl { +impl fmt::Display for clean::FnDecl { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "({args}){arrow}", args = self.inputs, arrow = self.output) } } -impl<'a> fmt::String for Method<'a> { +impl<'a> fmt::Display for Method<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let Method(selfty, d) = *self; let mut args = String::new(); @@ -599,7 +599,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for VisSpace { +impl fmt::Display for VisSpace { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.get() { Some(ast::Public) => write!(f, "pub "), @@ -608,7 +608,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for UnsafetySpace { +impl fmt::Display for UnsafetySpace { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.get() { ast::Unsafety::Unsafe => write!(f, "unsafe "), @@ -617,7 +617,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for clean::ViewPath { +impl fmt::Display for clean::Import { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { clean::SimpleImport(ref name, ref src) => { @@ -644,7 +644,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for clean::ImportSource { +impl fmt::Display for clean::ImportSource { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.did { Some(did) => resolved_path(f, did, &self.path, true), @@ -661,7 +661,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for clean::ViewListIdent { +impl fmt::Display for clean::ViewListIdent { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.source { Some(did) => { @@ -683,13 +683,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for clean::TypeBinding { +impl fmt::Display for clean::TypeBinding { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}={}", self.name, self.ty) } } -impl fmt::String for MutableSpace { +impl fmt::Display for MutableSpace { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { MutableSpace(clean::Immutable) => Ok(()), @@ -698,7 +698,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for RawMutableSpace { +impl fmt::Display for RawMutableSpace { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { RawMutableSpace(clean::Immutable) => write!(f, "const "), @@ -707,7 +707,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl<'a> fmt::String for Stability<'a> { +impl<'a> fmt::Display for Stability<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let Stability(stab) = *self; match *stab { @@ -721,7 +721,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl<'a> fmt::String for ConciseStability<'a> { +impl<'a> fmt::Display for ConciseStability<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let ConciseStability(stab) = *self; match *stab { @@ -738,7 +738,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl fmt::String for ModuleSummary { +impl fmt::Display for ModuleSummary { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt_inner<'a>(f: &mut fmt::Formatter, context: &mut Vec<&'a str>, diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs index db3319eb765..356be2ffeb0 100644 --- a/src/librustdoc/html/item_type.rs +++ b/src/librustdoc/html/item_type.rs @@ -22,29 +22,31 @@ #[derive(Copy, PartialEq, Clone)] pub enum ItemType { Module = 0, - Struct = 1, - Enum = 2, - Function = 3, - Typedef = 4, - Static = 5, - Trait = 6, - Impl = 7, - ViewItem = 8, - TyMethod = 9, - Method = 10, - StructField = 11, - Variant = 12, - // we used to have ForeignFunction and ForeignStatic. they are retired now. - Macro = 15, - Primitive = 16, - AssociatedType = 17, - Constant = 18, + ExternCrate = 1, + Import = 2, + Struct = 3, + Enum = 4, + Function = 5, + Typedef = 6, + Static = 7, + Trait = 8, + Impl = 9, + TyMethod = 10, + Method = 11, + StructField = 12, + Variant = 13, + Macro = 14, + Primitive = 15, + AssociatedType = 16, + Constant = 17, } impl ItemType { pub fn from_item(item: &clean::Item) -> ItemType { match item.inner { clean::ModuleItem(..) => ItemType::Module, + clean::ExternCrateItem(..) => ItemType::ExternCrate, + clean::ImportItem(..) => ItemType::Import, clean::StructItem(..) => ItemType::Struct, clean::EnumItem(..) => ItemType::Enum, clean::FunctionItem(..) => ItemType::Function, @@ -53,7 +55,6 @@ pub fn from_item(item: &clean::Item) -> ItemType { clean::ConstantItem(..) => ItemType::Constant, clean::TraitItem(..) => ItemType::Trait, clean::ImplItem(..) => ItemType::Impl, - clean::ViewItemItem(..) => ItemType::ViewItem, clean::TyMethodItem(..) => ItemType::TyMethod, clean::MethodItem(..) => ItemType::Method, clean::StructFieldItem(..) => ItemType::StructField, @@ -83,6 +84,8 @@ pub fn from_type_kind(kind: clean::TypeKind) -> ItemType { pub fn to_static_str(&self) -> &'static str { match *self { ItemType::Module => "mod", + ItemType::ExternCrate => "externcrate", + ItemType::Import => "import", ItemType::Struct => "struct", ItemType::Enum => "enum", ItemType::Function => "fn", @@ -90,7 +93,6 @@ pub fn to_static_str(&self) -> &'static str { ItemType::Static => "static", ItemType::Trait => "trait", ItemType::Impl => "impl", - ItemType::ViewItem => "viewitem", ItemType::TyMethod => "tymethod", ItemType::Method => "method", ItemType::StructField => "structfield", @@ -103,7 +105,7 @@ pub fn to_static_str(&self) -> &'static str { } } -impl fmt::String for ItemType { +impl fmt::Display for ItemType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.to_static_str().fmt(f) } diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index f75ab3f431c..e3bd2b4e27f 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -30,7 +30,7 @@ pub struct Page<'a> { pub keywords: &'a str } -pub fn render( +pub fn render( dst: &mut io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T) -> io::IoResult<()> { diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 0dbd13b4616..6f19519ee7c 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -146,7 +146,7 @@ fn hoedown_document_render(doc: *mut hoedown_document, fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> { let trimmed = s.trim(); if trimmed.starts_with("# ") { - Some(trimmed.slice_from(2)) + Some(&trimmed[2..]) } else { None } @@ -426,7 +426,7 @@ pub fn reset_headers() { USED_HEADER_MAP.with(|s| s.borrow_mut().clear()); } -impl<'a> fmt::String for Markdown<'a> { +impl<'a> fmt::Display for Markdown<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let Markdown(md) = *self; // This is actually common enough to special-case @@ -435,7 +435,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { } } -impl<'a> fmt::String for MarkdownWithToc<'a> { +impl<'a> fmt::Display for MarkdownWithToc<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let MarkdownWithToc(md) = *self; render(fmt, md.as_slice(), true) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index ab9700d966a..cd2ed5f0a97 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -35,7 +35,7 @@ pub use self::ExternalLocation::*; use std::cell::RefCell; -use std::cmp::Ordering::{self, Less, Greater, Equal}; +use std::cmp::Ordering; use std::collections::{HashMap, HashSet}; use std::default::Default; use std::fmt; @@ -404,7 +404,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::IoResult search_index.push(IndexItem { ty: shortty(item), name: item.name.clone().unwrap(), - path: fqp[..(fqp.len() - 1)].connect("::"), + path: fqp[..fqp.len() - 1].connect("::"), desc: shorter(item.doc_value()).to_string(), parent: Some(did), }); @@ -559,7 +559,7 @@ fn collect(path: &Path, krate: &str, }; let mut mydst = dst.clone(); - for part in remote_path[..(remote_path.len() - 1)].iter() { + for part in remote_path[..remote_path.len() - 1].iter() { mydst.push(part.as_slice()); try!(mkdir(&mydst)); } @@ -749,7 +749,7 @@ fn emit_source(&mut self, filename: &str) -> io::IoResult<()> { // Remove the utf-8 BOM if any let contents = if contents.starts_with("\u{feff}") { - contents.slice_from(3) + &contents[3..] } else { contents }; @@ -842,7 +842,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option { clean::StructFieldItem(..) | clean::VariantItem(..) => { ((Some(*self.parent_stack.last().unwrap()), - Some(&self.stack[..(self.stack.len() - 1)])), + Some(&self.stack[..self.stack.len() - 1])), false) } clean::MethodItem(..) => { @@ -853,13 +853,13 @@ fn fold_item(&mut self, item: clean::Item) -> Option { let did = *last; let path = match self.paths.get(&did) { Some(&(_, ItemType::Trait)) => - Some(&self.stack[..(self.stack.len() - 1)]), + Some(&self.stack[..self.stack.len() - 1]), // The current stack not necessarily has correlation for // where the type was defined. On the other hand, // `paths` always has the right information if present. Some(&(ref fqp, ItemType::Struct)) | Some(&(ref fqp, ItemType::Enum)) => - Some(&fqp[..(fqp.len() - 1)]), + Some(&fqp[..fqp.len() - 1]), Some(..) => Some(self.stack.as_slice()), None => None }; @@ -1185,7 +1185,7 @@ fn render(w: io::File, cx: &Context, it: &clean::Item, .collect::(); match cache().paths.get(&it.def_id) { Some(&(ref names, _)) => { - for name in (&names[..(names.len() - 1)]).iter() { + for name in (&names[..names.len() - 1]).iter() { url.push_str(name.as_slice()); url.push_str("/"); } @@ -1351,7 +1351,7 @@ fn href(&self, cx: &Context) -> Option { } -impl<'a> fmt::String for Item<'a> { +impl<'a> fmt::Display for Item<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { // Write the breadcrumb trail header for the top try!(write!(fmt, "\n

")); @@ -1469,7 +1469,7 @@ fn full_path(cx: &Context, item: &clean::Item) -> String { fn shorter<'a>(s: Option<&'a str>) -> &'a str { match s { Some(s) => match s.find_str("\n\n") { - Some(pos) => s.slice_to(pos), + Some(pos) => &s[..pos], None => s, }, None => "" @@ -1497,18 +1497,19 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, // the order of item types in the listing fn reorder(ty: ItemType) -> u8 { match ty { - ItemType::ViewItem => 0, - ItemType::Primitive => 1, - ItemType::Module => 2, - ItemType::Macro => 3, - ItemType::Struct => 4, - ItemType::Enum => 5, - ItemType::Constant => 6, - ItemType::Static => 7, - ItemType::Trait => 8, - ItemType::Function => 9, - ItemType::Typedef => 10, - _ => 11 + ty as u8, + ItemType::ExternCrate => 0, + ItemType::Import => 1, + ItemType::Primitive => 2, + ItemType::Module => 3, + ItemType::Macro => 4, + ItemType::Struct => 5, + ItemType::Enum => 6, + ItemType::Constant => 7, + ItemType::Static => 8, + ItemType::Trait => 9, + ItemType::Function => 10, + ItemType::Typedef => 12, + _ => 13 + ty as u8, } } @@ -1518,25 +1519,7 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering { if ty1 == ty2 { return i1.name.cmp(&i2.name); } - - let tycmp = reorder(ty1).cmp(&reorder(ty2)); - if let Equal = tycmp { - // for reexports, `extern crate` takes precedence. - match (&i1.inner, &i2.inner) { - (&clean::ViewItemItem(ref a), &clean::ViewItemItem(ref b)) => { - match (&a.inner, &b.inner) { - (&clean::ExternCrate(..), _) => return Less, - (_, &clean::ExternCrate(..)) => return Greater, - _ => {} - } - } - (_, _) => {} - } - - idx1.cmp(&idx2) - } else { - tycmp - } + (reorder(ty1), idx1).cmp(&(reorder(ty2), idx2)) } indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2)); @@ -1547,12 +1530,17 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering { let myitem = &items[idx]; let myty = Some(shortty(myitem)); - if myty != curty { + if curty == Some(ItemType::ExternCrate) && myty == Some(ItemType::Import) { + // Put `extern crate` and `use` re-exports in the same section. + curty = myty; + } else if myty != curty { if curty.is_some() { try!(write!(w, "")); } curty = myty; let (short, name) = match myty.unwrap() { + ItemType::ExternCrate | + ItemType::Import => ("reexports", "Reexports"), ItemType::Module => ("modules", "Modules"), ItemType::Struct => ("structs", "Structs"), ItemType::Enum => ("enums", "Enums"), @@ -1562,7 +1550,6 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering { ItemType::Constant => ("constants", "Constants"), ItemType::Trait => ("traits", "Traits"), ItemType::Impl => ("impls", "Implementations"), - ItemType::ViewItem => ("reexports", "Reexports"), ItemType::TyMethod => ("tymethods", "Type Methods"), ItemType::Method => ("methods", "Methods"), ItemType::StructField => ("fields", "Struct Fields"), @@ -1578,28 +1565,25 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering { } match myitem.inner { - clean::ViewItemItem(ref item) => { - match item.inner { - clean::ExternCrate(ref name, ref src, _) => { - match *src { - Some(ref src) => - try!(write!(w, "extern crate \"{}\" as {}", - src.as_slice(), - name.as_slice())), - None => - try!(write!(w, "extern crate {}", - name.as_slice())), - } - try!(write!(w, ";")); + clean::ExternCrateItem(ref name, ref src) => { + match *src { + Some(ref src) => { + try!(write!(w, "{}extern crate \"{}\" as {};", + VisSpace(myitem.visibility), + src.as_slice(), + name.as_slice())) } - - clean::Import(ref import) => { - try!(write!(w, "{}{}", - VisSpace(myitem.visibility), - *import)); + None => { + try!(write!(w, "{}extern crate {};", + VisSpace(myitem.visibility), name.as_slice())) } } + try!(write!(w, "")); + } + clean::ImportItem(ref import) => { + try!(write!(w, "{}{}", + VisSpace(myitem.visibility), *import)); } _ => { @@ -1626,7 +1610,7 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering { struct Initializer<'a>(&'a str); -impl<'a> fmt::String for Initializer<'a> { +impl<'a> fmt::Display for Initializer<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let Initializer(s) = *self; if s.len() == 0 { return Ok(()); } @@ -2085,6 +2069,10 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result { try!(write!(w, "

{}impl{} ", ConciseStability(&i.stability), i.impl_.generics)); + match i.impl_.polarity { + Some(clean::ImplPolarity::Negative) => try!(write!(w, "!")), + _ => {} + } match i.impl_.trait_ { Some(ref ty) => try!(write!(w, "{} for ", *ty)), None => {} @@ -2188,7 +2176,7 @@ fn item_typedef(w: &mut fmt::Formatter, it: &clean::Item, document(w, it) } -impl<'a> fmt::String for Sidebar<'a> { +impl<'a> fmt::Display for Sidebar<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let cx = self.cx; let it = self.item; @@ -2243,7 +2231,7 @@ fn block(w: &mut fmt::Formatter, short: &str, longty: &str, } } -impl<'a> fmt::String for Source<'a> { +impl<'a> fmt::Display for Source<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let Source(s) = *self; let lines = s.lines().count(); diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css index 5951ac2bae7..0914f93efd8 100644 --- a/src/librustdoc/html/static/main.css +++ b/src/librustdoc/html/static/main.css @@ -245,7 +245,6 @@ nav.sub { .content .highlighted.method { background-color: #c6afb3; } .content .highlighted.tymethod { background-color: #c6afb3; } .content .highlighted.type { background-color: #c6afb3; } -.content .highlighted.ffi { background-color: #c6afb3; } .docblock.short.nowrap { display: block; @@ -365,7 +364,6 @@ p a:hover { text-decoration: underline; } .content span.fn, .content a.fn, .block a.current.fn { color: #8c6067; } .content span.method, .content a.method, .block a.current.method { color: #8c6067; } .content span.tymethod, .content a.tymethod, .block a.current.tymethod { color: #8c6067; } -.content span.ffi, .content a.ffi, .block a.current.ffi { color: #8c6067; } .content .fnname { color: #8c6067; } .search-input { diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index f27f0cd70f4..1b0c3b00640 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -555,6 +555,8 @@ // This mapping table should match the discriminants of // `rustdoc::html::item_type::ItemType` type in Rust. var itemTypes = ["mod", + "externcrate", + "import", "struct", "enum", "fn", @@ -562,13 +564,10 @@ "static", "trait", "impl", - "viewitem", "tymethod", "method", "structfield", "variant", - "ffi", // retained for backward compatibility - "ffs", // retained for backward compatibility "macro", "primitive", "associatedtype", diff --git a/src/librustdoc/html/toc.rs b/src/librustdoc/html/toc.rs index 8d94e1857c4..aca6e5bb10e 100644 --- a/src/librustdoc/html/toc.rs +++ b/src/librustdoc/html/toc.rs @@ -176,13 +176,13 @@ pub fn push<'a>(&'a mut self, level: u32, name: String, id: String) -> &'a str { } } -impl fmt::Show for Toc { +impl fmt::Debug for Toc { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::String::fmt(self, f) + fmt::Display::fmt(self, f) } } -impl fmt::String for Toc { +impl fmt::Display for Toc { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { try!(write!(fmt, "