diff options
| author | Jeremy Soller <jackpot51@gmail.com> | 2016-10-31 09:40:24 -0600 |
|---|---|---|
| committer | Jeremy Soller <jackpot51@gmail.com> | 2016-10-31 09:40:24 -0600 |
| commit | 123d08b3d3901d5725af8303c1329b007089cde5 (patch) | |
| tree | f257a46a600bfcc8faa09d843f5dbe0aae8c7b3b | |
| parent | c77979b419959dda0d628ffb4af15c5f2a9e8648 (diff) | |
| parent | 074d30d030a3339565ab737c23312e6bbe625431 (diff) | |
| download | rust-123d08b3d3901d5725af8303c1329b007089cde5.tar.gz rust-123d08b3d3901d5725af8303c1329b007089cde5.zip | |
Merge branch 'master' of https://github.com/rust-lang/rust into redox
237 files changed, 2126 insertions, 2582 deletions
diff --git a/mk/cfg/aarch64-unknown-fuchsia.mk b/mk/cfg/aarch64-unknown-fuchsia.mk new file mode 100644 index 00000000000..34aee77ae21 --- /dev/null +++ b/mk/cfg/aarch64-unknown-fuchsia.mk @@ -0,0 +1 @@ +# rustbuild-only target diff --git a/mk/crates.mk b/mk/crates.mk index efe7a579801..25192bfd27a 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -60,8 +60,8 @@ RUSTC_CRATES := rustc rustc_typeck rustc_mir rustc_borrowck rustc_resolve rustc_ rustc_data_structures rustc_platform_intrinsics rustc_errors \ rustc_plugin rustc_metadata rustc_passes rustc_save_analysis \ rustc_const_eval rustc_const_math rustc_incremental proc_macro -HOST_CRATES := syntax syntax_ext proc_macro_plugin syntax_pos $(RUSTC_CRATES) rustdoc fmt_macros \ - flate arena graphviz log serialize +HOST_CRATES := syntax syntax_ext proc_macro_tokens proc_macro_plugin syntax_pos $(RUSTC_CRATES) \ + rustdoc fmt_macros flate arena graphviz log serialize TOOLS := compiletest rustdoc rustc rustbook error_index_generator DEPS_core := @@ -102,8 +102,9 @@ DEPS_test := std getopts term native:rust_test_helpers DEPS_syntax := std term serialize log arena libc rustc_bitflags rustc_unicode rustc_errors syntax_pos DEPS_syntax_ext := syntax syntax_pos rustc_errors fmt_macros proc_macro -DEPS_proc_macro_plugin := syntax syntax_pos rustc_plugin log DEPS_syntax_pos := serialize +DEPS_proc_macro_tokens := syntax syntax_pos log +DEPS_proc_macro_plugin := syntax syntax_pos rustc_plugin log proc_macro_tokens DEPS_rustc_const_math := std syntax log serialize DEPS_rustc_const_eval := rustc_const_math rustc syntax log serialize \ @@ -120,7 +121,7 @@ DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_bo rustc_trans rustc_privacy rustc_lint rustc_plugin \ rustc_metadata syntax_ext proc_macro_plugin \ rustc_passes rustc_save_analysis rustc_const_eval \ - rustc_incremental syntax_pos rustc_errors proc_macro + rustc_incremental syntax_pos rustc_errors proc_macro rustc_data_structures DEPS_rustc_errors := log libc serialize syntax_pos DEPS_rustc_lint := rustc log syntax syntax_pos rustc_const_eval DEPS_rustc_llvm := native:rustllvm libc std rustc_bitflags diff --git a/src/Cargo.lock b/src/Cargo.lock index 683ba90adf9..5826995cc3c 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -19,7 +19,7 @@ version = "0.0.0" dependencies = [ "build_helper 0.1.0", "core 0.0.0", - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.0.0", ] @@ -42,10 +42,10 @@ dependencies = [ "build_helper 0.1.0", "cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.35 (git+https://github.com/alexcrichton/gcc-rs)", + "gcc 0.3.38 (git+https://github.com/alexcrichton/gcc-rs)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", "md5 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -66,7 +66,7 @@ name = "cmake" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -83,7 +83,7 @@ name = "compiler_builtins" version = "0.0.0" dependencies = [ "core 0.0.0", - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -116,7 +116,7 @@ name = "filetime" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -124,7 +124,7 @@ name = "flate" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -133,12 +133,12 @@ version = "0.0.0" [[package]] name = "gcc" -version = "0.3.35" -source = "git+https://github.com/alexcrichton/gcc-rs#03e22a4425c011fa8c96681591432456fa70d60c" +version = "0.3.38" +source = "git+https://github.com/alexcrichton/gcc-rs#be620ac6d3ddb498cd0c700d5312c6a4c3c19597" [[package]] name = "gcc" -version = "0.3.35" +version = "0.3.38" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -159,7 +159,7 @@ name = "idna" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -182,14 +182,14 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "linkchecker" version = "0.1.0" dependencies = [ - "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -203,7 +203,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "matches" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -216,7 +216,7 @@ name = "num_cpus" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -249,12 +249,22 @@ name = "proc_macro_plugin" version = "0.0.0" dependencies = [ "log 0.0.0", + "proc_macro_tokens 0.0.0", "rustc_plugin 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] [[package]] +name = "proc_macro_tokens" +version = "0.0.0" +dependencies = [ + "log 0.0.0", + "syntax 0.0.0", + "syntax_pos 0.0.0", +] + +[[package]] name = "rand" version = "0.0.0" dependencies = [ @@ -373,6 +383,7 @@ dependencies = [ "rustc_back 0.0.0", "rustc_borrowck 0.0.0", "rustc_const_eval 0.0.0", + "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", "rustc_incremental 0.0.0", "rustc_lint 0.0.0", @@ -431,7 +442,7 @@ name = "rustc_llvm" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_bitflags 0.0.0", ] @@ -585,7 +596,7 @@ version = "0.0.0" dependencies = [ "arena 0.0.0", "build_helper 0.1.0", - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.0.0", "rustc 0.0.0", "rustc_back 0.0.0", @@ -621,7 +632,7 @@ dependencies = [ "collections 0.0.0", "compiler_builtins 0.0.0", "core 0.0.0", - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.0.0", "panic_abort 0.0.0", "panic_unwind 0.0.0", @@ -704,7 +715,7 @@ name = "unicode-bidi" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -714,11 +725,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "url" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -735,20 +746,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "dfcf5bcece56ef953b8ea042509e9dcbdfe97820b7e20d86beb53df30ed94978" "checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f" "checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922" -"checksum gcc 0.3.35 (git+https://github.com/alexcrichton/gcc-rs)" = "<none>" -"checksum gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "91ecd03771effb0c968fd6950b37e89476a578aaf1c70297d8e92b6516ec3312" +"checksum gcc 0.3.38 (git+https://github.com/alexcrichton/gcc-rs)" = "<none>" +"checksum gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "553f11439bdefe755bf366b264820f1da70f3aaf3924e594b886beb9c831bcf5" "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685" "checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "23e3757828fa702a20072c37ff47938e9dd331b92fac6e223d26d4b7a55f7ee2" +"checksum libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "044d1360593a78f5c8e5e710beccdc24ab71d1f01bc19a29bcacdba22e8475d8" "checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054" -"checksum matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "15305656809ce5a4805b1ff2946892810992197ce1270ff79baded852187942e" +"checksum matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc3ad8109fa4b522f9b0cd81440422781f564aaf8c195de6b9d6642177ad0dd" "checksum md5 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5539a8dee9b4ae308c9c406a379838b435a8f2c84cf9fedc6d5a576be9888db" "checksum num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "cee7e88156f3f9e19bdd598f8d6c9db7bf4078f99f8381f43a55b09648d1a6e3" "checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b" "checksum toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796" "checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f" "checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172" -"checksum url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afe9ec54bc4db14bc8744b7fed060d785ac756791450959b2248443319d5b119" +"checksum url 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ba5a45db1d2e0effb7a1c00cc73ffc63a973da8c7d1fcd5b46f24285ade6c54" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/src/doc/reference.md b/src/doc/reference.md index 84f459bf872..4838ecd2d42 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -4023,9 +4023,9 @@ Methods that take either `self` or `Box<Self>` can optionally place them in a mutable variable by prefixing them with `mut` (similar to regular arguments): ``` -trait Changer { - fn change(mut self) -> Self; - fn modify(mut self: Box<Self>) -> Box<Self>; +trait Changer: Sized { + fn change(mut self) {} + fn modify(mut self: Box<Self>) {} } ``` @@ -4078,6 +4078,12 @@ be ignored in favor of only building the artifacts specified by command line. Rust code into an existing non-Rust application because it will not have dynamic dependencies on other Rust code. +* `--crate-type=cdylib`, `#[crate_type = "cdylib"]` - A dynamic system + library will be produced. This is used when compiling Rust code as + a dynamic library to be loaded from another language. This output type will + create `*.so` files on Linux, `*.dylib` files on OSX, and `*.dll` files on + Windows. + * `--crate-type=rlib`, `#[crate_type = "rlib"]` - A "Rust library" file will be produced. This is used as an intermediate artifact and can be thought of as a "static Rust library". These `rlib` files, unlike `staticlib` files, are diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index b380ba180f4..a4fabb5a2c9 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -166,6 +166,7 @@ mod imp { fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID; fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID; fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL; + fn GetLastError() -> DWORD; } #[repr(C)] @@ -230,11 +231,11 @@ mod imp { pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, align: usize) { if align <= MIN_ALIGN { let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID); - debug_assert!(err != 0); + debug_assert!(err != 0, "Failed to free heap memory: {}", GetLastError()); } else { let header = get_header(ptr); let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID); - debug_assert!(err != 0); + debug_assert!(err != 0, "Failed to free heap memory: {}", GetLastError()); } } diff --git a/src/libcollectionstest/binary_heap.rs b/src/libcollectionstest/binary_heap.rs index faabcf4c372..9cd63d87931 100644 --- a/src/libcollectionstest/binary_heap.rs +++ b/src/libcollectionstest/binary_heap.rs @@ -299,5 +299,7 @@ fn test_extend_specialization() { #[allow(dead_code)] fn assert_covariance() { - fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d } + fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { + d + } } diff --git a/src/libcollectionstest/btree/map.rs b/src/libcollectionstest/btree/map.rs index 49fce68d15e..8222da105cc 100644 --- a/src/libcollectionstest/btree/map.rs +++ b/src/libcollectionstest/btree/map.rs @@ -533,9 +533,7 @@ create_append_test!(test_append_1700, 1700); fn rand_data(len: usize) -> Vec<(u32, u32)> { let mut rng = DeterministicRng::new(); - Vec::from_iter( - (0..len).map(|_| (rng.next(), rng.next())) - ) + Vec::from_iter((0..len).map(|_| (rng.next(), rng.next()))) } #[test] diff --git a/src/libcollectionstest/btree/mod.rs b/src/libcollectionstest/btree/mod.rs index ea43f423b7c..ae8b18d0c9f 100644 --- a/src/libcollectionstest/btree/mod.rs +++ b/src/libcollectionstest/btree/mod.rs @@ -25,7 +25,7 @@ impl DeterministicRng { x: 0x193a6754, y: 0xa8a7d469, z: 0x97830e05, - w: 0x113ba7bb + w: 0x113ba7bb, } } diff --git a/src/libcollectionstest/btree/set.rs b/src/libcollectionstest/btree/set.rs index a32e3f1a76a..6171b8ba624 100644 --- a/src/libcollectionstest/btree/set.rs +++ b/src/libcollectionstest/btree/set.rs @@ -15,45 +15,51 @@ use super::DeterministicRng; #[test] fn test_clone_eq() { - let mut m = BTreeSet::new(); + let mut m = BTreeSet::new(); - m.insert(1); - m.insert(2); + m.insert(1); + m.insert(2); - assert!(m.clone() == m); + assert!(m.clone() == m); } #[test] fn test_hash() { - let mut x = BTreeSet::new(); - let mut y = BTreeSet::new(); + let mut x = BTreeSet::new(); + let mut y = BTreeSet::new(); - x.insert(1); - x.insert(2); - x.insert(3); + x.insert(1); + x.insert(2); + x.insert(3); - y.insert(3); - y.insert(2); - y.insert(1); + y.insert(3); + y.insert(2); + y.insert(1); - assert!(::hash(&x) == ::hash(&y)); + assert!(::hash(&x) == ::hash(&y)); } -fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F) where - F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, &mut FnMut(&i32) -> bool) -> bool, +fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F) + where F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, &mut FnMut(&i32) -> bool) -> bool { let mut set_a = BTreeSet::new(); let mut set_b = BTreeSet::new(); - for x in a { assert!(set_a.insert(*x)) } - for y in b { assert!(set_b.insert(*y)) } + for x in a { + assert!(set_a.insert(*x)) + } + for y in b { + assert!(set_b.insert(*y)) + } let mut i = 0; - f(&set_a, &set_b, &mut |&x| { - assert_eq!(x, expected[i]); - i += 1; - true - }); + f(&set_a, + &set_b, + &mut |&x| { + assert_eq!(x, expected[i]); + i += 1; + true + }); assert_eq!(i, expected.len()); } @@ -82,9 +88,7 @@ fn test_difference() { check_difference(&[], &[], &[]); check_difference(&[1, 12], &[], &[1, 12]); check_difference(&[], &[1, 2, 3, 9], &[]); - check_difference(&[1, 3, 5, 9, 11], - &[3, 9], - &[1, 5, 11]); + check_difference(&[1, 3, 5, 9, 11], &[3, 9], &[1, 5, 11]); check_difference(&[-5, 11, 22, 33, 40, 42], &[-12, -5, 14, 23, 34, 38, 39, 50], &[11, 22, 33, 40, 42]); @@ -245,10 +249,18 @@ fn test_recovery() { fn test_variance() { use std::collections::btree_set::{IntoIter, Iter, Range}; - fn set<'new>(v: BTreeSet<&'static str>) -> BTreeSet<&'new str> { v } - fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> { v } - fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> { v } - fn range<'a, 'new>(v: Range<'a, &'static str>) -> Range<'a, &'new str> { v } + fn set<'new>(v: BTreeSet<&'static str>) -> BTreeSet<&'new str> { + v + } + fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> { + v + } + fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> { + v + } + fn range<'a, 'new>(v: Range<'a, &'static str>) -> Range<'a, &'new str> { + v + } } #[test] @@ -277,9 +289,7 @@ fn test_append() { fn rand_data(len: usize) -> Vec<u32> { let mut rng = DeterministicRng::new(); - Vec::from_iter( - (0..len).map(|_| rng.next()) - ) + Vec::from_iter((0..len).map(|_| rng.next())) } #[test] diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs index 88fb6540a9a..5d3e03c2dee 100644 --- a/src/libcollectionstest/lib.rs +++ b/src/libcollectionstest/lib.rs @@ -36,7 +36,9 @@ extern crate rustc_unicode; use std::hash::{Hash, Hasher}; use std::collections::hash_map::DefaultHasher; -#[cfg(test)] #[macro_use] mod bench; +#[cfg(test)] +#[macro_use] +mod bench; mod binary_heap; mod btree; diff --git a/src/libcollectionstest/slice.rs b/src/libcollectionstest/slice.rs index 130c16d7c15..a6230ef471c 100644 --- a/src/libcollectionstest/slice.rs +++ b/src/libcollectionstest/slice.rs @@ -420,12 +420,12 @@ fn test_sort_stability() { // number this element is, i.e. the second elements // will occur in sorted order. let mut v: Vec<_> = (0..len) - .map(|_| { - let n = thread_rng().gen::<usize>() % 10; - counts[n] += 1; - (n, counts[n]) - }) - .collect(); + .map(|_| { + let n = thread_rng().gen::<usize>() % 10; + counts[n] += 1; + (n, counts[n]) + }) + .collect(); // only sort on the first element, so an unstable sort // may mix up the counts. @@ -1116,13 +1116,13 @@ fn test_box_slice_clone_panics() { }; spawn(move || { - // When xs is dropped, +5. - let xs = vec![canary.clone(), canary.clone(), canary.clone(), panic, canary] - .into_boxed_slice(); + // When xs is dropped, +5. + let xs = vec![canary.clone(), canary.clone(), canary.clone(), panic, canary] + .into_boxed_slice(); - // When panic is cloned, +3. - xs.clone(); - }) + // When panic is cloned, +3. + xs.clone(); + }) .join() .unwrap_err(); @@ -1374,8 +1374,8 @@ mod bench { let mut rng = thread_rng(); b.iter(|| { let mut v = rng.gen_iter::<BigSortable>() - .take(5) - .collect::<Vec<BigSortable>>(); + .take(5) + .collect::<Vec<BigSortable>>(); v.sort(); }); b.bytes = 5 * mem::size_of::<BigSortable>() as u64; @@ -1386,8 +1386,8 @@ mod bench { let mut rng = thread_rng(); b.iter(|| { let mut v = rng.gen_iter::<BigSortable>() - .take(100) - .collect::<Vec<BigSortable>>(); + .take(100) + .collect::<Vec<BigSortable>>(); v.sort(); }); b.bytes = 100 * mem::size_of::<BigSortable>() as u64; @@ -1398,8 +1398,8 @@ mod bench { let mut rng = thread_rng(); b.iter(|| { let mut v = rng.gen_iter::<BigSortable>() - .take(10000) - .collect::<Vec<BigSortable>>(); + .take(10000) + .collect::<Vec<BigSortable>>(); v.sort(); }); b.bytes = 10000 * mem::size_of::<BigSortable>() as u64; diff --git a/src/libcollectionstest/vec.rs b/src/libcollectionstest/vec.rs index 9a04673d1da..3bc1321d756 100644 --- a/src/libcollectionstest/vec.rs +++ b/src/libcollectionstest/vec.rs @@ -607,8 +607,12 @@ fn test_from_cow() { #[allow(dead_code)] fn assert_covariance() { - fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d } - fn into_iter<'new>(i: IntoIter<&'static str>) -> IntoIter<&'new str> { i } + fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { + d + } + fn into_iter<'new>(i: IntoIter<&'static str>) -> IntoIter<&'new str> { + i + } } #[bench] diff --git a/src/libcollectionstest/vec_deque.rs b/src/libcollectionstest/vec_deque.rs index 9dfd3430268..f1ea85a6c5b 100644 --- a/src/libcollectionstest/vec_deque.rs +++ b/src/libcollectionstest/vec_deque.rs @@ -686,9 +686,9 @@ fn test_show() { assert_eq!(format!("{:?}", ringbuf), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"] - .iter() - .cloned() - .collect(); + .iter() + .cloned() + .collect(); assert_eq!(format!("{:?}", ringbuf), "[\"just\", \"one\", \"test\", \"more\"]"); } @@ -1003,5 +1003,7 @@ fn test_contains() { #[allow(dead_code)] fn assert_covariance() { - fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d } + fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { + d + } } diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 036633fe89d..e0f976e4161 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -706,24 +706,24 @@ mod impls { ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 } - #[unstable(feature = "never_type", issue = "35121")] + #[unstable(feature = "never_type_impls", issue = "35121")] impl PartialEq for ! { fn eq(&self, _: &!) -> bool { *self } } - #[unstable(feature = "never_type", issue = "35121")] + #[unstable(feature = "never_type_impls", issue = "35121")] impl Eq for ! {} - #[unstable(feature = "never_type", issue = "35121")] + #[unstable(feature = "never_type_impls", issue = "35121")] impl PartialOrd for ! { fn partial_cmp(&self, _: &!) -> Option<Ordering> { *self } } - #[unstable(feature = "never_type", issue = "35121")] + #[unstable(feature = "never_type_impls", issue = "35121")] impl Ord for ! { fn cmp(&self, _: &!) -> Ordering { *self diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 9aba6703386..2d75a8ec420 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1356,14 +1356,14 @@ macro_rules! fmt_refs { fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } -#[unstable(feature = "never_type", issue = "35121")] +#[unstable(feature = "never_type_impls", issue = "35121")] impl Debug for ! { fn fmt(&self, _: &mut Formatter) -> Result { *self } } -#[unstable(feature = "never_type", issue = "35121")] +#[unstable(feature = "never_type_impls", issue = "35121")] impl Display for ! { fn fmt(&self, _: &mut Formatter) -> Result { *self diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 5142b18dca1..e6c3f549ec8 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -553,7 +553,7 @@ pub mod builtin { /// For more information, see the documentation for [`std::concat_idents!`]. /// /// [`std::concat_idents!`]: ../std/macro.concat_idents.html - #[unstable(feature = "concat_idents", issue = "29599")] + #[unstable(feature = "concat_idents_macro", issue = "29599")] #[macro_export] macro_rules! concat_idents { ($($e:ident),*) => ({ /* compiler built-in */ }) diff --git a/src/liblibc b/src/liblibc -Subproject c95defce07a82f2f759f140c937dabd43a4f3d9 +Subproject 7d9b71f0971f8fa196d864d7071f216a59036d6 diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 4b9b92fb3bb..1d2c64d6d93 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -136,10 +136,8 @@ impl FromStr for TokenStream { fn from_str(src: &str) -> Result<TokenStream, LexError> { __internal::with_parse_sess(|sess| { let src = src.to_string(); - let cfg = Vec::new(); let name = "<proc-macro source code>".to_string(); - let mut parser = parse::new_parser_from_source_str(sess, cfg, name, - src); + let mut parser = parse::new_parser_from_source_str(sess, name, src); let mut ret = TokenStream { inner: Vec::new() }; loop { match parser.parse_item() { diff --git a/src/libproc_macro_plugin/Cargo.toml b/src/libproc_macro_plugin/Cargo.toml index 70bb86d0f58..4bc3f488d32 100644 --- a/src/libproc_macro_plugin/Cargo.toml +++ b/src/libproc_macro_plugin/Cargo.toml @@ -12,3 +12,4 @@ log = { path = "../liblog" } rustc_plugin = { path = "../librustc_plugin" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } +proc_macro_tokens = { path = "../libproc_macro_tokens" } diff --git a/src/libproc_macro_plugin/lib.rs b/src/libproc_macro_plugin/lib.rs index e82e97b5134..c45762bfb6e 100644 --- a/src/libproc_macro_plugin/lib.rs +++ b/src/libproc_macro_plugin/lib.rs @@ -13,43 +13,14 @@ //! A library for procedural macro writers. //! //! ## Usage -//! This package provides the `qquote!` macro for syntax creation, and the prelude -//! (at libproc_macro::prelude) provides a number of operations: -//! - `concat`, for concatenating two TokenStreams. -//! - `ident_eq`, for checking if two identifiers are equal regardless of syntax context. -//! - `str_to_token_ident`, for converting an `&str` into a Token. -//! - `keyword_to_token_delim`, for converting a `parse::token::keywords::Keyword` into a -//! Token. -//! - `build_delimited`, for creating a new TokenStream from an existing one and a delimiter -//! by wrapping the TokenStream in the delimiter. -//! - `build_bracket_delimited`, `build_brace_delimited`, and `build_paren_delimited`, for -//! easing the above. -//! - `build_empty_args`, which returns a TokenStream containing `()`. -//! - `lex`, which takes an `&str` and returns the TokenStream it represents. -//! -//! The `qquote!` macro also imports `syntax::ext::proc_macro_shim::prelude::*`, so you +//! This crate provides the `qquote!` macro for syntax creation. +//! +//! The `qquote!` macro imports `syntax::ext::proc_macro_shim::prelude::*`, so you //! will need to `extern crate syntax` for usage. (This is a temporary solution until more -//! of the external API in libproc_macro is stabilized to support the token construction +//! of the external API in libproc_macro_tokens is stabilized to support the token construction //! operations that the qausiquoter relies on.) The shim file also provides additional //! operations, such as `build_block_emitter` (as used in the `cond` example below). //! -//! ## TokenStreams -//! -//! TokenStreams serve as the basis of the macro system. They are, in essence, vectors of -//! TokenTrees, where indexing treats delimited values as a single term. That is, the term -//! `even(a+c) && even(b)` will be indexibly encoded as `even | (a+c) | even | (b)` where, -//! in reality, `(a+c)` is actually a decorated pointer to `a | + | c`. -//! -//! If a user has a TokenStream that is a single, delimited value, they can use -//! `maybe_delimited` to destruct it and receive the internal vector as a new TokenStream -//! as: -//! ``` -//! `(a+c)`.maybe_delimited() ~> Some(a | + | c)` -//! ``` -//! -//! Check the TokenStream documentation for more information; the structure also provides -//! cheap concatenation and slicing. -//! //! ## Quasiquotation //! //! The quasiquoter creates output that, when run, constructs the tokenstream specified as @@ -118,12 +89,11 @@ extern crate rustc_plugin; extern crate syntax; extern crate syntax_pos; +extern crate proc_macro_tokens; #[macro_use] extern crate log; mod qquote; -pub mod build; -pub mod parse; -pub mod prelude; + use qquote::qquote; use rustc_plugin::Registry; diff --git a/src/libproc_macro_plugin/qquote.rs b/src/libproc_macro_plugin/qquote.rs index b73d085656e..e5a3abc2ea9 100644 --- a/src/libproc_macro_plugin/qquote.rs +++ b/src/libproc_macro_plugin/qquote.rs @@ -24,12 +24,9 @@ //! TokenStream that resembles the output syntax. //! -extern crate rustc_plugin; -extern crate syntax; -extern crate syntax_pos; +use proc_macro_tokens::build::*; +use proc_macro_tokens::parse::lex; -use build::*; -use parse::lex; use qquote::int_build::*; use syntax::ast::Ident; @@ -51,7 +48,7 @@ pub fn qquote<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[TokenTree]) let output = qquoter(cx, TokenStream::from_tts(tts.clone().to_owned())); debug!("\nQQ out: {}\n", pprust::tts_to_string(&output.to_tts()[..])); let imports = concat(lex("use syntax::ext::proc_macro_shim::prelude::*;"), - lex("use proc_macro_plugin::prelude::*;")); + lex("use proc_macro_tokens::prelude::*;")); build_block_emitter(cx, sp, build_brace_delimited(concat(imports, output))) } @@ -219,7 +216,7 @@ fn convert_complex_tts<'cx>(cx: &'cx mut ExtCtxt, tts: Vec<QTT>) -> (Bindings, T let sep = build_delim_tok(qdl.delim); - pushes.push(build_mod_call(vec![str_to_ident("proc_macro_plugin"), + pushes.push(build_mod_call(vec![str_to_ident("proc_macro_tokens"), str_to_ident("build"), str_to_ident("build_delimited")], concat(from_tokens(vec![Token::Ident(new_id)]), @@ -264,11 +261,8 @@ fn is_qquote(id: Ident) -> bool { } mod int_build { - extern crate syntax; - extern crate syntax_pos; - - use parse::*; - use build::*; + use proc_macro_tokens::build::*; + use proc_macro_tokens::parse::*; use syntax::ast::{self, Ident}; use syntax::codemap::{DUMMY_SP}; diff --git a/src/libproc_macro_tokens/Cargo.toml b/src/libproc_macro_tokens/Cargo.toml new file mode 100644 index 00000000000..2b66d56759f --- /dev/null +++ b/src/libproc_macro_tokens/Cargo.toml @@ -0,0 +1,13 @@ +[package] +authors = ["The Rust Project Developers"] +name = "proc_macro_tokens" +version = "0.0.0" + +[lib] +path = "lib.rs" +crate-type = ["dylib"] + +[dependencies] +syntax = { path = "../libsyntax" } +syntax_pos = { path = "../libsyntax_pos" } +log = { path = "../liblog" } diff --git a/src/libproc_macro_plugin/build.rs b/src/libproc_macro_tokens/build.rs index 7b7590b863b..7b7590b863b 100644 --- a/src/libproc_macro_plugin/build.rs +++ b/src/libproc_macro_tokens/build.rs diff --git a/src/libproc_macro_tokens/lib.rs b/src/libproc_macro_tokens/lib.rs new file mode 100644 index 00000000000..3bfa2fbb29f --- /dev/null +++ b/src/libproc_macro_tokens/lib.rs @@ -0,0 +1,66 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! # Proc_Macro +//! +//! A library for procedural macro writers. +//! +//! ## Usage +//! This crate provides the prelude (at libproc_macro_tokens::prelude), which +//! provides a number of operations: +//! - `concat`, for concatenating two TokenStreams. +//! - `ident_eq`, for checking if two identifiers are equal regardless of syntax context. +//! - `str_to_token_ident`, for converting an `&str` into a Token. +//! - `keyword_to_token_delim`, for converting a `parse::token::keywords::Keyword` into a +//! Token. +//! - `build_delimited`, for creating a new TokenStream from an existing one and a delimiter +//! by wrapping the TokenStream in the delimiter. +//! - `build_bracket_delimited`, `build_brace_delimited`, and `build_paren_delimited`, for +//! easing the above. +//! - `build_empty_args`, which returns a TokenStream containing `()`. +//! - `lex`, which takes an `&str` and returns the TokenStream it represents. +//! +//! ## TokenStreams +//! +//! TokenStreams serve as the basis of the macro system. They are, in essence, vectors of +//! TokenTrees, where indexing treats delimited values as a single term. That is, the term +//! `even(a+c) && even(b)` will be indexibly encoded as `even | (a+c) | even | (b)` where, +//! in reality, `(a+c)` is actually a decorated pointer to `a | + | c`. +//! +//! If a user has a TokenStream that is a single, delimited value, they can use +//! `maybe_delimited` to destruct it and receive the internal vector as a new TokenStream +//! as: +//! ``` +//! `(a+c)`.maybe_delimited() ~> Some(a | + | c)` +//! ``` +//! +//! Check the TokenStream documentation for more information; the structure also provides +//! cheap concatenation and slicing. +//! + +#![crate_name = "proc_macro_tokens"] +#![unstable(feature = "rustc_private", issue = "27812")] +#![crate_type = "dylib"] +#![crate_type = "rlib"] +#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", + html_root_url = "https://doc.rust-lang.org/nightly/")] +#![cfg_attr(not(stage0), deny(warnings))] + +#![feature(staged_api)] +#![feature(rustc_private)] + +extern crate syntax; +extern crate syntax_pos; +#[macro_use] extern crate log; + +pub mod build; +pub mod parse; +pub mod prelude; diff --git a/src/libproc_macro_plugin/parse.rs b/src/libproc_macro_tokens/parse.rs index 9af8a68cdcf..9af8a68cdcf 100644 --- a/src/libproc_macro_plugin/parse.rs +++ b/src/libproc_macro_tokens/parse.rs diff --git a/src/libproc_macro_plugin/prelude.rs b/src/libproc_macro_tokens/prelude.rs index 4c0c8ba6c66..4c0c8ba6c66 100644 --- a/src/libproc_macro_plugin/prelude.rs +++ b/src/libproc_macro_tokens/prelude.rs diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 11f635847a0..620ee30c956 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -124,7 +124,6 @@ impl<'a> LoweringContext<'a> { hir::Crate { module: self.lower_mod(&c.module), attrs: self.lower_attrs(&c.attrs), - config: c.config.clone().into(), span: c.span, exported_macros: c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(), items: items, @@ -1219,7 +1218,7 @@ impl<'a> LoweringContext<'a> { alignstack, dialect, expn_id, - }) => hir::ExprInlineAsm(hir::InlineAsm { + }) => hir::ExprInlineAsm(P(hir::InlineAsm { inputs: inputs.iter().map(|&(ref c, _)| c.clone()).collect(), outputs: outputs.iter() .map(|out| { @@ -1237,7 +1236,7 @@ impl<'a> LoweringContext<'a> { alignstack: alignstack, dialect: dialect, expn_id: expn_id, - }, outputs.iter().map(|out| self.lower_expr(&out.expr)).collect(), + }), outputs.iter().map(|out| self.lower_expr(&out.expr)).collect(), inputs.iter().map(|&(_, ref input)| self.lower_expr(input)).collect()), ExprKind::Struct(ref path, ref fields, ref maybe_expr) => { hir::ExprStruct(self.lower_path(path), diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 1ac0a48713a..c451a789193 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -413,7 +413,6 @@ pub type CrateConfig = HirVec<P<MetaItem>>; pub struct Crate { pub module: Mod, pub attrs: HirVec<Attribute>, - pub config: CrateConfig, pub span: Span, pub exported_macros: HirVec<MacroDef>, @@ -941,7 +940,7 @@ pub enum Expr_ { ExprRet(Option<P<Expr>>), /// Inline assembly (from `asm!`), with its outputs and inputs. - ExprInlineAsm(InlineAsm, Vec<P<Expr>>, Vec<P<Expr>>), + ExprInlineAsm(P<InlineAsm>, HirVec<P<Expr>>, HirVec<P<Expr>>), /// A struct or struct-like variant literal expression. /// diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 25731df4778..d17402d2134 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -105,23 +105,12 @@ pub mod middle { pub mod weak_lang_items; } -pub mod mir { - mod cache; - pub mod repr; - pub mod tcx; - pub mod visit; - pub mod transform; - pub mod traversal; - pub mod mir_map; -} - +pub mod mir; pub mod session; pub mod traits; pub mod ty; pub mod util { - pub use rustc_back::sha2; - pub mod common; pub mod ppaux; pub mod nodemap; diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 4ef42bb68eb..3472c77cf42 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -192,6 +192,12 @@ declare_lint! { "safe access to extern statics was erroneously allowed" } +declare_lint! { + pub PATTERNS_IN_FNS_WITHOUT_BODY, + Warn, + "patterns in functions without body were erroneously allowed" +} + /// Does nothing as a lint pass, but registers some `Lint`s /// which are used by other parts of the compiler. #[derive(Copy, Clone)] @@ -228,7 +234,8 @@ impl LintPass for HardwiredLints { SUPER_OR_SELF_IN_GLOBAL_PATH, HR_LIFETIME_IN_ASSOC_TYPE, LIFETIME_UNDERSCORE, - SAFE_EXTERN_STATICS + SAFE_EXTERN_STATICS, + PATTERNS_IN_FNS_WITHOUT_BODY ) } } diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index a3a84f51780..59a5147ed1c 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -29,8 +29,7 @@ use hir::map::definitions::{Definitions, DefKey}; use hir::svh::Svh; use middle::lang_items; use ty::{self, Ty, TyCtxt}; -use mir::repr::Mir; -use mir::mir_map::MirMap; +use mir::Mir; use session::Session; use session::search_paths::PathKind; use util::nodemap::{NodeSet, DefIdMap}; @@ -165,7 +164,6 @@ pub trait CrateStore<'tcx> { fn is_const_fn(&self, did: DefId) -> bool; fn is_defaulted_trait(&self, did: DefId) -> bool; fn is_default_impl(&self, impl_did: DefId) -> bool; - fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool; fn is_foreign_item(&self, did: DefId) -> bool; fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool; @@ -209,8 +207,7 @@ pub trait CrateStore<'tcx> { fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option<ast::NodeId>; fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId>; - fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Option<Mir<'tcx>>; + fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx>; fn is_item_mir_available(&self, def: DefId) -> bool; // This is basically a 1-based range of ints, which is a little @@ -228,8 +225,7 @@ pub trait CrateStore<'tcx> { fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, reexports: &def::ExportMap, link_meta: &LinkMeta, - reachable: &NodeSet, - mir_map: &MirMap<'tcx>) -> Vec<u8>; + reachable: &NodeSet) -> Vec<u8>; fn metadata_encoding_version(&self) -> &[u8]; } @@ -334,8 +330,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") } fn is_defaulted_trait(&self, did: DefId) -> bool { bug!("is_defaulted_trait") } fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") } - fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool - { bug!("is_extern_item") } fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") } fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false } @@ -390,8 +384,8 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { bug!("defid_for_inlined_node") } - fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Option<Mir<'tcx>> { bug!("maybe_get_item_mir") } + fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) + -> Mir<'tcx> { bug!("get_item_mir") } fn is_item_mir_available(&self, def: DefId) -> bool { bug!("is_item_mir_available") } @@ -412,8 +406,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, reexports: &def::ExportMap, link_meta: &LinkMeta, - reachable: &NodeSet, - mir_map: &MirMap<'tcx>) -> Vec<u8> { vec![] } + reachable: &NodeSet) -> Vec<u8> { vec![] } fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") } } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 799c02b7403..c37b6df369d 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -1017,7 +1017,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { delegate.matched_pat(pat, downcast_cmt, match_mode); } Some(Def::Struct(..)) | Some(Def::StructCtor(..)) | Some(Def::Union(..)) | - Some(Def::TyAlias(..)) | Some(Def::AssociatedTy(..)) => { + Some(Def::TyAlias(..)) | Some(Def::AssociatedTy(..)) | Some(Def::SelfTy(..)) => { debug!("struct cmt_pat={:?} pat={:?}", cmt_pat, pat); delegate.matched_pat(pat, cmt_pat, match_mode); } diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs index 1be7d00f072..bc9bbebb179 100644 --- a/src/librustc/mir/cache.rs +++ b/src/librustc/mir/cache.rs @@ -11,7 +11,7 @@ use std::cell::{Ref, RefCell}; use rustc_data_structures::indexed_vec::IndexVec; -use mir::repr::{Mir, BasicBlock}; +use mir::{Mir, BasicBlock}; use rustc_serialize as serialize; diff --git a/src/librustc/mir/mir_map.rs b/src/librustc/mir/mir_map.rs deleted file mode 100644 index 92de65798d3..00000000000 --- a/src/librustc/mir/mir_map.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig}; -use hir::def_id::DefId; -use mir::repr::Mir; -use std::marker::PhantomData; - -pub struct MirMap<'tcx> { - pub map: DepTrackingMap<MirMapConfig<'tcx>>, -} - -impl<'tcx> MirMap<'tcx> { - pub fn new(graph: DepGraph) -> Self { - MirMap { - map: DepTrackingMap::new(graph) - } - } -} - -pub struct MirMapConfig<'tcx> { - data: PhantomData<&'tcx ()> -} - -impl<'tcx> DepTrackingMapConfig for MirMapConfig<'tcx> { - type Key = DefId; - type Value = Mir<'tcx>; - fn to_dep_node(key: &DefId) -> DepNode<DefId> { - DepNode::Mir(*key) - } -} diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/mod.rs index fa899c40269..9d82006ac9f 100644 --- a/src/librustc/mir/repr.rs +++ b/src/librustc/mir/mod.rs @@ -32,7 +32,11 @@ use std::vec::IntoIter; use syntax::ast::{self, Name}; use syntax_pos::Span; -use super::cache::Cache; +mod cache; +pub mod tcx; +pub mod visit; +pub mod transform; +pub mod traversal; macro_rules! newtype_index { ($name:ident, $debug_name:expr) => ( @@ -59,7 +63,8 @@ macro_rules! newtype_index { } /// Lowered representation of a single function. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +// Do not implement clone for Mir, its easy to do so accidently and its kind of expensive. +#[derive(RustcEncodable, RustcDecodable, Debug)] pub struct Mir<'tcx> { /// List of basic blocks. References to basic block use a newtyped index type `BasicBlock` /// that indexes into this vector. @@ -106,7 +111,7 @@ pub struct Mir<'tcx> { pub span: Span, /// A cache for various calculations - cache: Cache + cache: cache::Cache } /// where execution begins @@ -137,7 +142,7 @@ impl<'tcx> Mir<'tcx> { upvar_decls: upvar_decls, spread_arg: None, span: span, - cache: Cache::new() + cache: cache::Cache::new() } } @@ -1138,8 +1143,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { AggregateKind::Adt(adt_def, variant, substs, _) => { let variant_def = &adt_def.variants[variant]; - ppaux::parameterized(fmt, substs, variant_def.did, - ppaux::Ns::Value, &[])?; + ppaux::parameterized(fmt, substs, variant_def.did, &[])?; match variant_def.ctor_kind { CtorKind::Const => Ok(()), @@ -1234,7 +1238,7 @@ impl<'tcx> Debug for Literal<'tcx> { use self::Literal::*; match *self { Item { def_id, substs } => { - ppaux::parameterized(fmt, substs, def_id, ppaux::Ns::Value, &[]) + ppaux::parameterized(fmt, substs, def_id, &[]) } Value { ref value } => { write!(fmt, "const ")?; diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 8dd82b2d079..f9afbaf104a 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -13,7 +13,7 @@ * building is complete. */ -use mir::repr::*; +use mir::*; use ty::subst::{Subst, Substs}; use ty::{self, AdtDef, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; diff --git a/src/librustc/mir/transform.rs b/src/librustc/mir/transform.rs index 8cd5f5844d2..3576ae662a0 100644 --- a/src/librustc/mir/transform.rs +++ b/src/librustc/mir/transform.rs @@ -11,8 +11,7 @@ use dep_graph::DepNode; use hir; use hir::map::DefPathData; -use mir::mir_map::MirMap; -use mir::repr::{Mir, Promoted}; +use mir::{Mir, Promoted}; use ty::TyCtxt; use syntax::ast::NodeId; use util::common::time; @@ -85,12 +84,11 @@ pub trait Pass { fn disambiguator<'a>(&'a self) -> Option<Box<fmt::Display+'a>> { None } } -/// A pass which inspects the whole MirMap. +/// A pass which inspects the whole Mir map. pub trait MirMapPass<'tcx>: Pass { fn run_pass<'a>( &mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - map: &mut MirMap<'tcx>, hooks: &mut [Box<for<'s> MirPassHook<'s>>]); } @@ -114,13 +112,18 @@ pub trait MirPass<'tcx>: Pass { impl<'tcx, T: MirPass<'tcx>> MirMapPass<'tcx> for T { fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - map: &mut MirMap<'tcx>, hooks: &mut [Box<for<'s> MirPassHook<'s>>]) { - let def_ids = map.map.keys(); + let def_ids = tcx.mir_map.borrow().keys(); for def_id in def_ids { + if !def_id.is_local() { + continue; + } + let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id)); - let mir = map.map.get_mut(&def_id).unwrap(); + let mir = &mut tcx.mir_map.borrow()[&def_id].borrow_mut(); + tcx.dep_graph.write(DepNode::Mir(def_id)); + let id = tcx.map.as_local_node_id(def_id).unwrap(); let src = MirSource::from_node(tcx, id); @@ -163,11 +166,11 @@ impl<'a, 'tcx> Passes { passes } - pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, map: &mut MirMap<'tcx>) { + pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) { let Passes { ref mut passes, ref mut plugin_passes, ref mut pass_hooks } = *self; for pass in plugin_passes.iter_mut().chain(passes.iter_mut()) { time(tcx.sess.time_passes(), &*pass.name(), - || pass.run_pass(tcx, map, pass_hooks)); + || pass.run_pass(tcx, pass_hooks)); } } diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs index 1af5123b4df..6057e7ec7e0 100644 --- a/src/librustc/mir/traversal.rs +++ b/src/librustc/mir/traversal.rs @@ -13,7 +13,7 @@ use std::vec; use rustc_data_structures::bitvec::BitVector; use rustc_data_structures::indexed_vec::Idx; -use super::repr::*; +use super::*; /// Preorder traversal of a graph. /// diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index cb8d3f97f7b..db7267ca0d4 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -12,7 +12,7 @@ use middle::const_val::ConstVal; use hir::def_id::DefId; use ty::subst::Substs; use ty::{ClosureSubsts, Region, Ty}; -use mir::repr::*; +use mir::*; use rustc_const_math::ConstUsize; use rustc_data_structures::tuple_slice::TupleSlice; use rustc_data_structures::indexed_vec::Idx; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 0ad53529dd1..7b5413984a2 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1237,10 +1237,9 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> { pub fn parse_cfgspecs(cfgspecs: Vec<String> ) -> ast::CrateConfig { cfgspecs.into_iter().map(|s| { let sess = parse::ParseSess::new(); - let mut parser = parse::new_parser_from_source_str(&sess, - Vec::new(), - "cfgspec".to_string(), - s.to_string()); + let mut parser = + parse::new_parser_from_source_str(&sess, "cfgspec".to_string(), s.to_string()); + let meta_item = panictry!(parser.parse_meta_item()); if !parser.reader.is_eof() { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 8c7a2da3be7..62cc78141db 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -22,6 +22,7 @@ use middle::free_region::FreeRegionMap; use middle::region::RegionMaps; use middle::resolve_lifetime; use middle::stability; +use mir::Mir; use ty::subst::{Kind, Substs}; use traits; use ty::{self, TraitRef, Ty, TypeAndMut}; @@ -65,8 +66,9 @@ pub struct CtxtArenas<'tcx> { // references generics: TypedArena<ty::Generics<'tcx>>, - trait_defs: TypedArena<ty::TraitDef<'tcx>>, - adt_defs: TypedArena<ty::AdtDefData<'tcx, 'tcx>>, + trait_def: TypedArena<ty::TraitDef<'tcx>>, + adt_def: TypedArena<ty::AdtDefData<'tcx, 'tcx>>, + mir: TypedArena<RefCell<Mir<'tcx>>>, } impl<'tcx> CtxtArenas<'tcx> { @@ -81,8 +83,9 @@ impl<'tcx> CtxtArenas<'tcx> { layout: TypedArena::new(), generics: TypedArena::new(), - trait_defs: TypedArena::new(), - adt_defs: TypedArena::new() + trait_def: TypedArena::new(), + adt_def: TypedArena::new(), + mir: TypedArena::new() } } } @@ -358,6 +361,15 @@ pub struct GlobalCtxt<'tcx> { pub map: ast_map::Map<'tcx>, + /// Maps from the def-id of a function/method or const/static + /// to its MIR. Mutation is done at an item granularity to + /// allow MIR optimization passes to function and still + /// access cross-crate MIR (e.g. inlining or const eval). + /// + /// Note that cross-crate MIR appears to be always borrowed + /// (in the `RefCell` sense) to prevent accidental mutation. + pub mir_map: RefCell<DepTrackingMap<maps::Mir<'tcx>>>, + // Records the free variables refrenced by every closure // expression. Do not track deps for this, just recompute it from // scratch every time. @@ -604,6 +616,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.global_interners.arenas.generics.alloc(generics) } + pub fn alloc_mir(self, mir: Mir<'gcx>) -> &'gcx RefCell<Mir<'gcx>> { + self.global_interners.arenas.mir.alloc(RefCell::new(mir)) + } + pub fn intern_trait_def(self, def: ty::TraitDef<'gcx>) -> &'gcx ty::TraitDef<'gcx> { let did = def.trait_ref.def_id; @@ -617,7 +633,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn alloc_trait_def(self, def: ty::TraitDef<'gcx>) -> &'gcx ty::TraitDef<'gcx> { - self.global_interners.arenas.trait_defs.alloc(def) + self.global_interners.arenas.trait_def.alloc(def) } pub fn insert_adt_def(self, did: DefId, adt_def: ty::AdtDefMaster<'gcx>) { @@ -633,7 +649,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { variants: Vec<ty::VariantDefData<'gcx, 'gcx>>) -> ty::AdtDefMaster<'gcx> { let def = ty::AdtDefData::new(self, did, kind, variants); - let interned = self.global_interners.arenas.adt_defs.alloc(def); + let interned = self.global_interners.arenas.adt_def.alloc(def); self.insert_adt_def(did, interned); interned } @@ -738,6 +754,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { super_predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())), fulfilled_predicates: RefCell::new(fulfilled_predicates), map: map, + mir_map: RefCell::new(DepTrackingMap::new(dep_graph.clone())), freevars: RefCell::new(freevars), maybe_unused_trait_imports: maybe_unused_trait_imports, tcache: RefCell::new(DepTrackingMap::new(dep_graph.clone())), diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 3a552a8b437..cad87081a93 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -10,7 +10,10 @@ use dep_graph::{DepNode, DepTrackingMapConfig}; use hir::def_id::DefId; +use mir; use ty::{self, Ty}; + +use std::cell::RefCell; use std::marker::PhantomData; use std::rc::Rc; use syntax::{attr, ast}; @@ -43,3 +46,4 @@ dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Vec<DefId> } dep_map_ty! { TraitItems: TraitItems(DefId) -> Rc<Vec<ty::ImplOrTraitItem<'tcx>>> } dep_map_ty! { ReprHints: ReprHints(DefId) -> Rc<Vec<attr::ReprAttr>> } dep_map_ty! { InlinedClosures: Hir(DefId) -> ast::NodeId } +dep_map_ty! { Mir: Mir(DefId) -> &'tcx RefCell<mir::Mir<'tcx>> } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f65976a8c11..588857e557c 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -24,6 +24,7 @@ use hir::def::{Def, CtorKind, PathResolution, ExportMap}; use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use middle::region::{CodeExtent, ROOT_CODE_EXTENT}; +use mir::Mir; use traits; use ty; use ty::subst::{Subst, Substs}; @@ -34,7 +35,7 @@ use util::nodemap::FnvHashMap; use serialize::{self, Encodable, Encoder}; use std::borrow::Cow; -use std::cell::{Cell, RefCell}; +use std::cell::{Cell, RefCell, Ref}; use std::hash::{Hash, Hasher}; use std::iter; use std::ops::Deref; @@ -1698,7 +1699,7 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> { match def { Def::Variant(vid) | Def::VariantCtor(vid, ..) => self.variant_with_id(vid), Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) | - Def::TyAlias(..) | Def::AssociatedTy(..) => self.struct_variant(), + Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => self.struct_variant(), _ => bug!("unexpected def {:?} in variant_of_def", def) } } @@ -2519,6 +2520,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { || self.sess.cstore.item_super_predicates(self.global_tcx(), did)) } + /// Given the did of an item, returns its MIR, borrowed immutably. + pub fn item_mir(self, did: DefId) -> Ref<'gcx, Mir<'gcx>> { + lookup_locally_or_in_crate_store("mir_map", did, &self.mir_map, || { + let mir = self.sess.cstore.get_item_mir(self.global_tcx(), did); + let mir = self.alloc_mir(mir); + + // Perma-borrow MIR from extern crates to prevent mutation. + mem::forget(mir.borrow()); + + mir + }).borrow() + } + /// If `type_needs_drop` returns true, then `ty` is definitely /// non-copy and *might* have a destructor attached; if it returns /// false, then `ty` definitely has no destructor (i.e. no drop glue). diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index bb36fa1487e..cca4069ba5a 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -405,6 +405,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// /// The same goes for endianess: We always convert multi-byte integers to little /// endian before hashing. +#[derive(Debug)] pub struct ArchIndependentHasher<H> { inner: H, } @@ -413,6 +414,10 @@ impl<H> ArchIndependentHasher<H> { pub fn new(inner: H) -> ArchIndependentHasher<H> { ArchIndependentHasher { inner: inner } } + + pub fn into_inner(self) -> H { + self.inner + } } impl<H: Hasher> Hasher for ArchIndependentHasher<H> { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index af92569cc35..5ca56741029 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -9,12 +9,13 @@ // except according to those terms. use hir::def_id::DefId; +use hir::map::definitions::DefPathData; use ty::subst::{self, Subst}; use ty::{BrAnon, BrEnv, BrFresh, BrNamed}; use ty::{TyBool, TyChar, TyAdt}; use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr}; use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple}; -use ty::TyClosure; +use ty::{TyClosure, TyProjection, TyAnon}; use ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer}; use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::fold::{TypeFolder, TypeVisitor}; @@ -56,17 +57,9 @@ fn fn_sig(f: &mut fmt::Formatter, Ok(()) } -/// Namespace of the path given to parameterized to print. -#[derive(Copy, Clone, PartialEq, Debug)] -pub enum Ns { - Type, - Value -} - pub fn parameterized(f: &mut fmt::Formatter, substs: &subst::Substs, did: DefId, - ns: Ns, projections: &[ty::ProjectionPredicate]) -> fmt::Result { let mut verbose = false; @@ -75,8 +68,34 @@ pub fn parameterized(f: &mut fmt::Formatter, let mut num_regions = 0; let mut num_types = 0; let mut item_name = None; + let mut is_value_path = false; let fn_trait_kind = ty::tls::with(|tcx| { - let mut generics = tcx.lookup_generics(did); + // Unfortunately, some kinds of items (e.g., closures) don't have + // generics. So walk back up the find the closest parent that DOES + // have them. + let mut item_def_id = did; + loop { + let key = tcx.def_key(item_def_id); + match key.disambiguated_data.data { + DefPathData::TypeNs(_) => { + break; + } + DefPathData::ValueNs(_) | DefPathData::EnumVariant(_) => { + is_value_path = true; + break; + } + _ => { + // if we're making a symbol for something, there ought + // to be a value or type-def or something in there + // *somewhere* + item_def_id.index = key.parent.unwrap_or_else(|| { + bug!("finding type for {:?}, encountered def-id {:?} with no \ + parent", did, item_def_id); + }); + } + } + } + let mut generics = tcx.lookup_generics(item_def_id); let mut path_def_id = did; verbose = tcx.sess.verbose(); has_self = generics.has_self; @@ -84,7 +103,7 @@ pub fn parameterized(f: &mut fmt::Formatter, let mut child_types = 0; if let Some(def_id) = generics.parent { // Methods. - assert_eq!(ns, Ns::Value); + assert!(is_value_path); child_types = generics.types.len(); generics = tcx.lookup_generics(def_id); num_regions = generics.regions.len(); @@ -97,7 +116,7 @@ pub fn parameterized(f: &mut fmt::Formatter, item_name = Some(tcx.item_name(did)); path_def_id = def_id; } else { - if ns == Ns::Value { + if is_value_path { // Functions. assert_eq!(has_self, false); } else { @@ -192,7 +211,7 @@ pub fn parameterized(f: &mut fmt::Formatter, start_or_continue(f, "", ">")?; // For values, also print their name and type parameters. - if ns == Ns::Value { + if is_value_path { empty.set(true); if has_self { @@ -298,7 +317,6 @@ impl<'tcx> fmt::Display for TraitAndProjections<'tcx> { let TraitAndProjections(ref trait_ref, ref projection_bounds) = *self; parameterized(f, trait_ref.substs, trait_ref.def_id, - Ns::Type, projection_bounds) } } @@ -398,7 +416,7 @@ impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> { let trait_ref = tcx.lift(&ty::Binder(*self)) .expect("could not lift TraitRef for printing") .with_self_ty(tcx, dummy_self).0; - parameterized(f, trait_ref.substs, trait_ref.def_id, Ns::Type, &[]) + parameterized(f, trait_ref.substs, trait_ref.def_id, &[]) }) } } @@ -798,7 +816,7 @@ impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<&'tcx ty::Region, impl<'tcx> fmt::Display for ty::TraitRef<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - parameterized(f, self.substs, self.def_id, Ns::Type, &[]) + parameterized(f, self.substs, self.def_id, &[]) } } @@ -851,7 +869,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { } write!(f, "{} {{", bare_fn.sig.0)?; - parameterized(f, substs, def_id, Ns::Value, &[])?; + parameterized(f, substs, def_id, &[])?; write!(f, "}}") } TyFnPtr(ref bare_fn) => { @@ -874,13 +892,13 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { !tcx.tcache.borrow().contains_key(&def.did) { write!(f, "{}<..>", tcx.item_path_str(def.did)) } else { - parameterized(f, substs, def.did, Ns::Type, &[]) + parameterized(f, substs, def.did, &[]) } }) } TyTrait(ref data) => write!(f, "{}", data), - ty::TyProjection(ref data) => write!(f, "{}", data), - ty::TyAnon(def_id, substs) => { + TyProjection(ref data) => write!(f, "{}", data), + TyAnon(def_id, substs) => { ty::tls::with(|tcx| { // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, // by looking up the projections associated with the def_id. diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index e6d1982d31c..da5f787bdf3 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -36,9 +36,8 @@ #![feature(rand)] #![feature(rustc_private)] #![feature(staged_api)] -#![feature(step_by)] #![cfg_attr(stage0, feature(question_mark))] -#![cfg_attr(test, feature(test, rand))] +#![cfg_attr(test, feature(rand))] extern crate syntax; extern crate libc; @@ -48,7 +47,6 @@ extern crate serialize; extern crate serialize as rustc_serialize; // used by deriving pub mod tempdir; -pub mod sha2; pub mod target; pub mod slice; pub mod dynamic_lib; diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs deleted file mode 100644 index 97fb39c17ea..00000000000 --- a/src/librustc_back/sha2.rs +++ /dev/null @@ -1,679 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! This module implements only the Sha256 function since that is all that is needed for internal -//! use. This implementation is not intended for external use or for any use where security is -//! important. - -use serialize::hex::ToHex; - -/// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian -/// format. -fn write_u32_be(dst: &mut[u8], input: u32) { - dst[0] = (input >> 24) as u8; - dst[1] = (input >> 16) as u8; - dst[2] = (input >> 8) as u8; - dst[3] = input as u8; -} - -/// Read the value of a vector of bytes as a u32 value in big-endian format. -fn read_u32_be(input: &[u8]) -> u32 { - (input[0] as u32) << 24 | - (input[1] as u32) << 16 | - (input[2] as u32) << 8 | - (input[3] as u32) -} - -/// Read a vector of bytes into a vector of u32s. The values are read in big-endian format. -fn read_u32v_be(dst: &mut[u32], input: &[u8]) { - assert!(dst.len() * 4 == input.len()); - let mut pos = 0; - for chunk in input.chunks(4) { - dst[pos] = read_u32_be(chunk); - pos += 1; - } -} - -trait ToBits: Sized { - /// Convert the value in bytes to the number of bits, a tuple where the 1st item is the - /// high-order value and the 2nd item is the low order value. - fn to_bits(self) -> (Self, Self); -} - -impl ToBits for u64 { - fn to_bits(self) -> (u64, u64) { - (self >> 61, self << 3) - } -} - -/// Adds the specified number of bytes to the bit count. panic!() if this would cause numeric -/// overflow. -fn add_bytes_to_bits(bits: u64, bytes: u64) -> u64 { - let (new_high_bits, new_low_bits) = bytes.to_bits(); - - if new_high_bits > 0 { - panic!("numeric overflow occurred.") - } - - match bits.checked_add(new_low_bits) { - Some(x) => x, - None => panic!("numeric overflow occurred.") - } -} - -/// A FixedBuffer, likes its name implies, is a fixed size buffer. When the buffer becomes full, it -/// must be processed. The input() method takes care of processing and then clearing the buffer -/// automatically. However, other methods do not and require the caller to process the buffer. Any -/// method that modifies the buffer directory or provides the caller with bytes that can be modified -/// results in those bytes being marked as used by the buffer. -trait FixedBuffer { - /// Input a vector of bytes. If the buffer becomes full, process it with the provided - /// function and then clear the buffer. - fn input<F>(&mut self, input: &[u8], func: F) where - F: FnMut(&[u8]); - - /// Reset the buffer. - fn reset(&mut self); - - /// Zero the buffer up until the specified index. The buffer position currently must not be - /// greater than that index. - fn zero_until(&mut self, idx: usize); - - /// Get a slice of the buffer of the specified size. There must be at least that many bytes - /// remaining in the buffer. - fn next<'s>(&'s mut self, len: usize) -> &'s mut [u8]; - - /// Get the current buffer. The buffer must already be full. This clears the buffer as well. - fn full_buffer<'s>(&'s mut self) -> &'s [u8]; - - /// Get the current position of the buffer. - fn position(&self) -> usize; - - /// Get the number of bytes remaining in the buffer until it is full. - fn remaining(&self) -> usize; - - /// Get the size of the buffer - fn size(&self) -> usize; -} - -/// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize. -struct FixedBuffer64 { - buffer: [u8; 64], - buffer_idx: usize, -} - -impl FixedBuffer64 { - /// Create a new FixedBuffer64 - fn new() -> FixedBuffer64 { - FixedBuffer64 { - buffer: [0; 64], - buffer_idx: 0 - } - } -} - -impl FixedBuffer for FixedBuffer64 { - fn input<F>(&mut self, input: &[u8], mut func: F) where - F: FnMut(&[u8]), - { - let mut i = 0; - - let size = self.size(); - - // If there is already data in the buffer, copy as much as we can into it and process - // the data if the buffer becomes full. - if self.buffer_idx != 0 { - let buffer_remaining = size - self.buffer_idx; - if input.len() >= buffer_remaining { - self.buffer[self.buffer_idx..size] - .copy_from_slice(&input[..buffer_remaining]); - self.buffer_idx = 0; - func(&self.buffer); - i += buffer_remaining; - } else { - self.buffer[self.buffer_idx..self.buffer_idx + input.len()] - .copy_from_slice(input); - self.buffer_idx += input.len(); - return; - } - } - - // 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]); - i += size; - } - - // Copy any input data into the buffer. At this point in the method, the amount of - // data left in the input vector will be less than the buffer size and the buffer will - // be empty. - let input_remaining = input.len() - i; - self.buffer[..input_remaining].copy_from_slice(&input[i..]); - self.buffer_idx += input_remaining; - } - - fn reset(&mut self) { - self.buffer_idx = 0; - } - - fn zero_until(&mut self, idx: usize) { - assert!(idx >= self.buffer_idx); - for slot in self.buffer[self.buffer_idx..idx].iter_mut() { - *slot = 0; - } - self.buffer_idx = idx; - } - - fn next<'s>(&'s mut self, len: usize) -> &'s mut [u8] { - self.buffer_idx += len; - &mut self.buffer[self.buffer_idx - len..self.buffer_idx] - } - - fn full_buffer<'s>(&'s mut self) -> &'s [u8] { - assert!(self.buffer_idx == 64); - self.buffer_idx = 0; - &self.buffer[..64] - } - - fn position(&self) -> usize { self.buffer_idx } - - fn remaining(&self) -> usize { 64 - self.buffer_idx } - - fn size(&self) -> usize { 64 } -} - -/// The StandardPadding trait adds a method useful for Sha256 to a FixedBuffer struct. -trait StandardPadding { - /// Add padding to the buffer. The buffer must not be full when this method is called and is - /// guaranteed to have exactly rem remaining bytes when it returns. If there are not at least - /// rem bytes available, the buffer will be zero padded, processed, cleared, and then filled - /// with zeros again until only rem bytes are remaining. - fn standard_padding<F>(&mut self, rem: usize, func: F) where F: FnMut(&[u8]); -} - -impl <T: FixedBuffer> StandardPadding for T { - fn standard_padding<F>(&mut self, rem: usize, mut func: F) where F: FnMut(&[u8]) { - let size = self.size(); - - self.next(1)[0] = 128; - - if self.remaining() < rem { - self.zero_until(size); - func(self.full_buffer()); - } - - self.zero_until(size - rem); - } -} - -/// The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2 -/// family of digest functions. -pub trait Digest { - /// Provide message data. - /// - /// # Arguments - /// - /// * input - A vector of message data - fn input(&mut self, input: &[u8]); - - /// Retrieve the digest result. This method may be called multiple times. - /// - /// # Arguments - /// - /// * out - the vector to hold the result. Must be large enough to contain output_bits(). - fn result(&mut self, out: &mut [u8]); - - /// Reset the digest. This method must be called after result() and before supplying more - /// data. - fn reset(&mut self); - - /// Get the output size in bits. - fn output_bits(&self) -> usize; - - /// Convenience function that feeds a string into a digest. - /// - /// # Arguments - /// - /// * `input` The string to feed into the digest - fn input_str(&mut self, input: &str) { - self.input(input.as_bytes()); - } - - /// Convenience function that retrieves the result of a digest as a - /// newly allocated vec of bytes. - fn result_bytes(&mut self) -> Vec<u8> { - let mut buf = vec![0; (self.output_bits()+7)/8]; - self.result(&mut buf); - buf - } - - /// Convenience function that retrieves the result of a digest as a - /// String in hexadecimal format. - fn result_str(&mut self) -> String { - self.result_bytes().to_hex().to_string() - } -} - -// A structure that represents that state of a digest computation for the SHA-2 512 family of digest -// functions -struct Engine256State { - h0: u32, - h1: u32, - h2: u32, - h3: u32, - h4: u32, - h5: u32, - h6: u32, - h7: u32, -} - -impl Engine256State { - fn new(h: &[u32; 8]) -> Engine256State { - Engine256State { - h0: h[0], - h1: h[1], - h2: h[2], - h3: h[3], - h4: h[4], - h5: h[5], - h6: h[6], - h7: h[7] - } - } - - fn reset(&mut self, h: &[u32; 8]) { - self.h0 = h[0]; - self.h1 = h[1]; - self.h2 = h[2]; - self.h3 = h[3]; - self.h4 = h[4]; - self.h5 = h[5]; - self.h6 = h[6]; - self.h7 = h[7]; - } - - fn process_block(&mut self, data: &[u8]) { - fn ch(x: u32, y: u32, z: u32) -> u32 { - ((x & y) ^ ((!x) & z)) - } - - fn maj(x: u32, y: u32, z: u32) -> u32 { - ((x & y) ^ (x & z) ^ (y & z)) - } - - fn sum0(x: u32) -> u32 { - ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10)) - } - - fn sum1(x: u32) -> u32 { - ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7)) - } - - fn sigma0(x: u32) -> u32 { - ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3) - } - - fn sigma1(x: u32) -> u32 { - ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10) - } - - let mut a = self.h0; - let mut b = self.h1; - let mut c = self.h2; - let mut d = self.h3; - let mut e = self.h4; - let mut f = self.h5; - let mut g = self.h6; - let mut h = self.h7; - - let mut w = [0; 64]; - - // Sha-512 and Sha-256 use basically the same calculations which are implemented - // by these macros. Inlining the calculations seems to result in better generated code. - macro_rules! schedule_round { ($t:expr) => ( - w[$t] = sigma1(w[$t - 2]).wrapping_add(w[$t - 7]) - .wrapping_add(sigma0(w[$t - 15])).wrapping_add(w[$t - 16]); - ) - } - - macro_rules! sha2_round { - ($A:ident, $B:ident, $C:ident, $D:ident, - $E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => ( - { - $H = $H.wrapping_add(sum1($E)).wrapping_add(ch($E, $F, $G)) - .wrapping_add($K[$t]).wrapping_add(w[$t]); - $D = $D.wrapping_add($H); - $H = $H.wrapping_add(sum0($A)).wrapping_add(maj($A, $B, $C)); - } - ) - } - - read_u32v_be(&mut w[0..16], data); - - // Putting the message schedule inside the same loop as the round calculations allows for - // the compiler to generate better code. - for t in (0..48).step_by(8) { - schedule_round!(t + 16); - schedule_round!(t + 17); - schedule_round!(t + 18); - schedule_round!(t + 19); - schedule_round!(t + 20); - schedule_round!(t + 21); - schedule_round!(t + 22); - schedule_round!(t + 23); - - sha2_round!(a, b, c, d, e, f, g, h, K32, t); - sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1); - sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2); - sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3); - sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4); - sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5); - sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6); - sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7); - } - - for t in (48..64).step_by(8) { - sha2_round!(a, b, c, d, e, f, g, h, K32, t); - sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1); - sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2); - sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3); - sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4); - sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5); - sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6); - sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7); - } - - self.h0 = self.h0.wrapping_add(a); - self.h1 = self.h1.wrapping_add(b); - self.h2 = self.h2.wrapping_add(c); - self.h3 = self.h3.wrapping_add(d); - self.h4 = self.h4.wrapping_add(e); - self.h5 = self.h5.wrapping_add(f); - self.h6 = self.h6.wrapping_add(g); - self.h7 = self.h7.wrapping_add(h); - } -} - -static K32: [u32; 64] = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -]; - -// A structure that keeps track of the state of the Sha-256 operation and contains the logic -// necessary to perform the final calculations. -struct Engine256 { - length_bits: u64, - buffer: FixedBuffer64, - state: Engine256State, - finished: bool, -} - -impl Engine256 { - fn new(h: &[u32; 8]) -> Engine256 { - Engine256 { - length_bits: 0, - buffer: FixedBuffer64::new(), - state: Engine256State::new(h), - finished: false - } - } - - fn reset(&mut self, h: &[u32; 8]) { - self.length_bits = 0; - self.buffer.reset(); - self.state.reset(h); - self.finished = false; - } - - fn input(&mut self, input: &[u8]) { - assert!(!self.finished); - // Assumes that input.len() can be converted to u64 without overflow - self.length_bits = add_bytes_to_bits(self.length_bits, input.len() as u64); - let self_state = &mut self.state; - self.buffer.input(input, |input: &[u8]| { self_state.process_block(input) }); - } - - fn finish(&mut self) { - if !self.finished { - let self_state = &mut self.state; - self.buffer.standard_padding(8, |input: &[u8]| { self_state.process_block(input) }); - write_u32_be(self.buffer.next(4), (self.length_bits >> 32) as u32 ); - write_u32_be(self.buffer.next(4), self.length_bits as u32); - self_state.process_block(self.buffer.full_buffer()); - - self.finished = true; - } - } -} - -/// The SHA-256 hash algorithm -pub struct Sha256 { - engine: Engine256 -} - -impl Sha256 { - /// Construct a new instance of a SHA-256 digest. - /// Do not – under any circumstances – use this where timing attacks might be possible! - pub fn new() -> Sha256 { - Sha256 { - engine: Engine256::new(&H256) - } - } -} - -impl Digest for Sha256 { - fn input(&mut self, d: &[u8]) { - self.engine.input(d); - } - - fn result(&mut self, out: &mut [u8]) { - self.engine.finish(); - - write_u32_be(&mut out[0..4], self.engine.state.h0); - write_u32_be(&mut out[4..8], self.engine.state.h1); - write_u32_be(&mut out[8..12], self.engine.state.h2); - write_u32_be(&mut out[12..16], self.engine.state.h3); - write_u32_be(&mut out[16..20], self.engine.state.h4); - write_u32_be(&mut out[20..24], self.engine.state.h5); - write_u32_be(&mut out[24..28], self.engine.state.h6); - write_u32_be(&mut out[28..32], self.engine.state.h7); - } - - fn reset(&mut self) { - self.engine.reset(&H256); - } - - fn output_bits(&self) -> usize { 256 } -} - -static H256: [u32; 8] = [ - 0x6a09e667, - 0xbb67ae85, - 0x3c6ef372, - 0xa54ff53a, - 0x510e527f, - 0x9b05688c, - 0x1f83d9ab, - 0x5be0cd19 -]; - -#[cfg(test)] -mod tests { - #![allow(deprecated)] - extern crate rand; - - use self::rand::Rng; - use self::rand::isaac::IsaacRng; - use serialize::hex::FromHex; - use std::u64; - use super::{Digest, Sha256}; - - // A normal addition - no overflow occurs - #[test] - fn test_add_bytes_to_bits_ok() { - assert!(super::add_bytes_to_bits(100, 10) == 180); - } - - // A simple failure case - adding 1 to the max value - #[test] - #[should_panic] - fn test_add_bytes_to_bits_overflow() { - super::add_bytes_to_bits(u64::MAX, 1); - } - - struct Test { - input: String, - output_str: String, - } - - fn test_hash<D: Digest>(sh: &mut D, tests: &[Test]) { - // Test that it works when accepting the message all at once - for t in tests { - sh.reset(); - sh.input_str(&t.input); - let out_str = sh.result_str(); - assert!(out_str == t.output_str); - } - - // Test that it works when accepting the message in pieces - for t in tests { - sh.reset(); - let len = t.input.len(); - let mut left = len; - while left > 0 { - let take = (left + 1) / 2; - sh.input_str(&t.input[len - left..take + len - left]); - left = left - take; - } - let out_str = sh.result_str(); - assert!(out_str == t.output_str); - } - } - - #[test] - fn test_sha256() { - // Examples from wikipedia - let wikipedia_tests = vec!( - Test { - input: "".to_string(), - output_str: "e3b0c44298fc1c149afb\ - f4c8996fb92427ae41e4649b934ca495991b7852b855".to_string() - }, - Test { - input: "The quick brown fox jumps over the lazy \ - dog".to_string(), - output_str: "d7a8fbb307d7809469ca\ - 9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592".to_string() - }, - Test { - input: "The quick brown fox jumps over the lazy \ - dog.".to_string(), - output_str: "ef537f25c895bfa78252\ - 6529a9b63d97aa631564d5d789c2b765448c8635fb6c".to_string() - }); - - let tests = wikipedia_tests; - - let mut sh: Box<_> = box Sha256::new(); - - test_hash(&mut *sh, &tests); - } - - /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is - /// correct. - fn test_digest_1million_random<D: Digest>(digest: &mut D, blocksize: usize, expected: &str) { - let total_size = 1000000; - let buffer = vec![b'a'; blocksize * 2]; - let mut rng = IsaacRng::new_unseeded(); - let mut count = 0; - - digest.reset(); - - while count < total_size { - let next: usize = rng.gen_range(0, 2 * blocksize + 1); - let remaining = total_size - count; - let size = if next > remaining { remaining } else { next }; - digest.input(&buffer[..size]); - count += size; - } - - let result_str = digest.result_str(); - let result_bytes = digest.result_bytes(); - - assert_eq!(expected, result_str); - - let expected_vec: Vec<u8> = expected.from_hex() - .unwrap() - .into_iter() - .collect(); - assert_eq!(expected_vec, result_bytes); - } - - #[test] - fn test_1million_random_sha256() { - let mut sh = Sha256::new(); - test_digest_1million_random( - &mut sh, - 64, - "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"); - } -} - -#[cfg(test)] -mod bench { - extern crate test; - use self::test::Bencher; - use super::{Sha256, Digest}; - - #[bench] - pub fn sha256_10(b: &mut Bencher) { - let mut sh = Sha256::new(); - let bytes = [1; 10]; - b.iter(|| { - sh.input(&bytes); - }); - b.bytes = bytes.len() as u64; - } - - #[bench] - pub fn sha256_1k(b: &mut Bencher) { - let mut sh = Sha256::new(); - let bytes = [1; 1024]; - b.iter(|| { - sh.input(&bytes); - }); - b.bytes = bytes.len() as u64; - } - - #[bench] - pub fn sha256_64k(b: &mut Bencher) { - let mut sh = Sha256::new(); - let bytes = [1; 65536]; - b.iter(|| { - sh.input(&bytes); - }); - b.bytes = bytes.len() as u64; - } -} diff --git a/src/librustc_back/target/aarch64_unknown_fuchsia.rs b/src/librustc_back/target/aarch64_unknown_fuchsia.rs new file mode 100644 index 00000000000..a93a46d1402 --- /dev/null +++ b/src/librustc_back/target/aarch64_unknown_fuchsia.rs @@ -0,0 +1,28 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use target::{Target, TargetResult}; + +pub fn target() -> TargetResult { + let mut base = super::fuchsia_base::opts(); + base.max_atomic_width = Some(128); + + Ok(Target { + llvm_target: "aarch64-unknown-fuchsia".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), + arch: "aarch64".to_string(), + target_os: "fuchsia".to_string(), + target_env: "".to_string(), + target_vendor: "unknown".to_string(), + options: base, + }) +} diff --git a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs b/src/librustc_back/target/aarch64_unknown_linux_gnu.rs index b031de76fc3..5f6335d405f 100644 --- a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs +++ b/src/librustc_back/target/aarch64_unknown_linux_gnu.rs @@ -13,6 +13,10 @@ use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); base.max_atomic_width = Some(128); + + // see #36994 + base.exe_allocation_crate = "alloc_system".to_string(); + Ok(Target { llvm_target: "aarch64-unknown-linux-gnu".to_string(), target_endian: "little".to_string(), diff --git a/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs b/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs index 9f0b6fcc436..c284840ecb4 100644 --- a/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs +++ b/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs @@ -25,6 +25,10 @@ pub fn target() -> TargetResult { cpu: "mips64r2".to_string(), features: "+mips64r2".to_string(), max_atomic_width: Some(64), + + // see #36994 + exe_allocation_crate: "alloc_system".to_string(), + ..super::linux_base::opts() }, }) diff --git a/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs b/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs index 9c4531c5b21..17895836fe8 100644 --- a/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs +++ b/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs @@ -25,6 +25,10 @@ pub fn target() -> TargetResult { cpu: "mips64r2".to_string(), features: "+mips64r2".to_string(), max_atomic_width: Some(64), + + // see #36994 + exe_allocation_crate: "alloc_system".to_string(), + ..super::linux_base::opts() }, }) diff --git a/src/librustc_back/target/mips_unknown_linux_gnu.rs b/src/librustc_back/target/mips_unknown_linux_gnu.rs index e744dce2bb4..a6d8fae2536 100644 --- a/src/librustc_back/target/mips_unknown_linux_gnu.rs +++ b/src/librustc_back/target/mips_unknown_linux_gnu.rs @@ -24,6 +24,10 @@ pub fn target() -> TargetResult { cpu: "mips32r2".to_string(), features: "+mips32r2".to_string(), max_atomic_width: Some(32), + + // see #36994 + exe_allocation_crate: "alloc_system".to_string(), + ..super::linux_base::opts() }, }) diff --git a/src/librustc_back/target/mips_unknown_linux_musl.rs b/src/librustc_back/target/mips_unknown_linux_musl.rs index 4254c1b83e3..e4a6d2a55d9 100644 --- a/src/librustc_back/target/mips_unknown_linux_musl.rs +++ b/src/librustc_back/target/mips_unknown_linux_musl.rs @@ -24,6 +24,10 @@ pub fn target() -> TargetResult { cpu: "mips32r2".to_string(), features: "+mips32r2,+soft-float".to_string(), max_atomic_width: Some(32), + + // see #36994 + exe_allocation_crate: "alloc_system".to_string(), + ..super::linux_base::opts() } }) diff --git a/src/librustc_back/target/mips_unknown_linux_uclibc.rs b/src/librustc_back/target/mips_unknown_linux_uclibc.rs index e6b2672a8e3..ccc64ea393b 100644 --- a/src/librustc_back/target/mips_unknown_linux_uclibc.rs +++ b/src/librustc_back/target/mips_unknown_linux_uclibc.rs @@ -24,6 +24,10 @@ pub fn target() -> TargetResult { cpu: "mips32r2".to_string(), features: "+mips32r2,+soft-float".to_string(), max_atomic_width: Some(32), + + // see #36994 + exe_allocation_crate: "alloc_system".to_string(), + ..super::linux_base::opts() }, }) diff --git a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs b/src/librustc_back/target/mipsel_unknown_linux_gnu.rs index 4949055861e..9b8b1d5713f 100644 --- a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs +++ b/src/librustc_back/target/mipsel_unknown_linux_gnu.rs @@ -25,6 +25,10 @@ pub fn target() -> TargetResult { cpu: "mips32".to_string(), features: "+mips32".to_string(), max_atomic_width: Some(32), + + // see #36994 + exe_allocation_crate: "alloc_system".to_string(), + ..super::linux_base::opts() }, }) diff --git a/src/librustc_back/target/mipsel_unknown_linux_musl.rs b/src/librustc_back/target/mipsel_unknown_linux_musl.rs index f282ac7e88b..5693bddd048 100644 --- a/src/librustc_back/target/mipsel_unknown_linux_musl.rs +++ b/src/librustc_back/target/mipsel_unknown_linux_musl.rs @@ -24,6 +24,10 @@ pub fn target() -> TargetResult { cpu: "mips32".to_string(), features: "+mips32,+soft-float".to_string(), max_atomic_width: Some(32), + + // see #36994 + exe_allocation_crate: "alloc_system".to_string(), + ..super::linux_base::opts() } }) diff --git a/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs b/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs index 0f9b562068f..3acade5a474 100644 --- a/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs +++ b/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs @@ -25,6 +25,10 @@ pub fn target() -> TargetResult { cpu: "mips32".to_string(), features: "+mips32,+soft-float".to_string(), max_atomic_width: Some(32), + + // see #36994 + exe_allocation_crate: "alloc_system".to_string(), + ..super::linux_base::opts() }, }) diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index fc52f46a514..4d9315a1a3b 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -177,6 +177,7 @@ supported_targets! { ("x86_64-apple-darwin", x86_64_apple_darwin), ("i686-apple-darwin", i686_apple_darwin), + ("aarch64-unknown-fuchsia", aarch64_unknown_fuchsia), ("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia), ("i386-apple-ios", i386_apple_ios), diff --git a/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs b/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs index 333bfad4a26..909c5488dcb 100644 --- a/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs +++ b/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs @@ -16,6 +16,9 @@ pub fn target() -> TargetResult { base.pre_link_args.push("-m64".to_string()); base.max_atomic_width = Some(64); + // see #36994 + base.exe_allocation_crate = "alloc_system".to_string(); + Ok(Target { llvm_target: "powerpc64-unknown-linux-gnu".to_string(), target_endian: "big".to_string(), diff --git a/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs b/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs index e75da133314..a692346ca0f 100644 --- a/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs +++ b/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs @@ -16,6 +16,9 @@ pub fn target() -> TargetResult { base.pre_link_args.push("-m64".to_string()); base.max_atomic_width = Some(64); + // see #36994 + base.exe_allocation_crate = "alloc_system".to_string(); + Ok(Target { llvm_target: "powerpc64le-unknown-linux-gnu".to_string(), target_endian: "little".to_string(), diff --git a/src/librustc_back/target/powerpc_unknown_linux_gnu.rs b/src/librustc_back/target/powerpc_unknown_linux_gnu.rs index 45d28dd031f..284772c4331 100644 --- a/src/librustc_back/target/powerpc_unknown_linux_gnu.rs +++ b/src/librustc_back/target/powerpc_unknown_linux_gnu.rs @@ -15,6 +15,9 @@ pub fn target() -> TargetResult { base.pre_link_args.push("-m32".to_string()); base.max_atomic_width = Some(32); + // see #36994 + base.exe_allocation_crate = "alloc_system".to_string(); + Ok(Target { llvm_target: "powerpc-unknown-linux-gnu".to_string(), target_endian: "big".to_string(), diff --git a/src/librustc_borrowck/borrowck/mir/abs_domain.rs b/src/librustc_borrowck/borrowck/mir/abs_domain.rs index 155b615d83c..dc450433ad9 100644 --- a/src/librustc_borrowck/borrowck/mir/abs_domain.rs +++ b/src/librustc_borrowck/borrowck/mir/abs_domain.rs @@ -21,8 +21,8 @@ //! `a[x]` would still overlap them both. But that is not this //! representation does today.) -use rustc::mir::repr::{Lvalue, LvalueElem}; -use rustc::mir::repr::{Operand, Projection, ProjectionElem}; +use rustc::mir::{Lvalue, LvalueElem}; +use rustc::mir::{Operand, Projection, ProjectionElem}; #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct AbstractOperand; diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs b/src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs index f6260527039..28f58723862 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs @@ -11,7 +11,7 @@ //! Hook into libgraphviz for rendering dataflow graphs for MIR. use syntax::ast::NodeId; -use rustc::mir::repr::{BasicBlock, Mir}; +use rustc::mir::{BasicBlock, Mir}; use rustc_data_structures::bitslice::bits_to_string; use rustc_data_structures::indexed_set::{IdxSet}; use rustc_data_structures::indexed_vec::Idx; diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs b/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs index dce167975cf..fcb453d81aa 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs @@ -9,7 +9,7 @@ // except according to those terms. use rustc::ty::TyCtxt; -use rustc::mir::repr::{self, Mir, Location}; +use rustc::mir::{self, Mir, Location}; use rustc_data_structures::bitslice::BitSlice; // adds set_bit/get_bit to &[usize] bitvector rep. use rustc_data_structures::bitslice::{BitwiseOperator}; use rustc_data_structures::indexed_set::{IdxSet}; @@ -245,7 +245,7 @@ impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> { fn statement_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<MovePathIndex>, - bb: repr::BasicBlock, + bb: mir::BasicBlock, idx: usize) { drop_flag_effects_for_location( @@ -258,7 +258,7 @@ impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> { fn terminator_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<MovePathIndex>, - bb: repr::BasicBlock, + bb: mir::BasicBlock, statements_len: usize) { drop_flag_effects_for_location( @@ -271,9 +271,9 @@ impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> { fn propagate_call_return(&self, ctxt: &Self::Ctxt, in_out: &mut IdxSet<MovePathIndex>, - _call_bb: repr::BasicBlock, - _dest_bb: repr::BasicBlock, - dest_lval: &repr::Lvalue) { + _call_bb: mir::BasicBlock, + _dest_bb: mir::BasicBlock, + dest_lval: &mir::Lvalue) { // when a call returns successfully, that means we need to set // the bits for that dest_lval to 1 (initialized). on_lookup_result_bits(self.tcx, self.mir, &ctxt.move_data, @@ -306,7 +306,7 @@ impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> { fn statement_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<MovePathIndex>, - bb: repr::BasicBlock, + bb: mir::BasicBlock, idx: usize) { drop_flag_effects_for_location( @@ -319,7 +319,7 @@ impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> { fn terminator_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<MovePathIndex>, - bb: repr::BasicBlock, + bb: mir::BasicBlock, statements_len: usize) { drop_flag_effects_for_location( @@ -332,9 +332,9 @@ impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> { fn propagate_call_return(&self, ctxt: &Self::Ctxt, in_out: &mut IdxSet<MovePathIndex>, - _call_bb: repr::BasicBlock, - _dest_bb: repr::BasicBlock, - dest_lval: &repr::Lvalue) { + _call_bb: mir::BasicBlock, + _dest_bb: mir::BasicBlock, + dest_lval: &mir::Lvalue) { // when a call returns successfully, that means we need to set // the bits for that dest_lval to 0 (initialized). on_lookup_result_bits(self.tcx, self.mir, &ctxt.move_data, @@ -366,7 +366,7 @@ impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> { fn statement_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<MovePathIndex>, - bb: repr::BasicBlock, + bb: mir::BasicBlock, idx: usize) { drop_flag_effects_for_location( @@ -379,7 +379,7 @@ impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> { fn terminator_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<MovePathIndex>, - bb: repr::BasicBlock, + bb: mir::BasicBlock, statements_len: usize) { drop_flag_effects_for_location( @@ -392,9 +392,9 @@ impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> { fn propagate_call_return(&self, ctxt: &Self::Ctxt, in_out: &mut IdxSet<MovePathIndex>, - _call_bb: repr::BasicBlock, - _dest_bb: repr::BasicBlock, - dest_lval: &repr::Lvalue) { + _call_bb: mir::BasicBlock, + _dest_bb: mir::BasicBlock, + dest_lval: &mir::Lvalue) { // when a call returns successfully, that means we need to set // the bits for that dest_lval to 1 (initialized). on_lookup_result_bits(self.tcx, self.mir, &ctxt.move_data, @@ -418,7 +418,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> { fn statement_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<MoveOutIndex>, - bb: repr::BasicBlock, + bb: mir::BasicBlock, idx: usize) { let (tcx, mir, move_data) = (self.tcx, self.mir, &ctxt.move_data); let stmt = &mir[bb].statements[idx]; @@ -437,10 +437,10 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> { } let bits_per_block = self.bits_per_block(ctxt); match stmt.kind { - repr::StatementKind::SetDiscriminant { .. } => { + mir::StatementKind::SetDiscriminant { .. } => { span_bug!(stmt.source_info.span, "SetDiscriminant should not exist in borrowck"); } - repr::StatementKind::Assign(ref lvalue, _) => { + mir::StatementKind::Assign(ref lvalue, _) => { // assigning into this `lvalue` kills all // MoveOuts from it, and *also* all MoveOuts // for children and associated fragment sets. @@ -453,16 +453,16 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> { sets.kill_set.add(&moi); }); } - repr::StatementKind::StorageLive(_) | - repr::StatementKind::StorageDead(_) | - repr::StatementKind::Nop => {} + mir::StatementKind::StorageLive(_) | + mir::StatementKind::StorageDead(_) | + mir::StatementKind::Nop => {} } } fn terminator_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<MoveOutIndex>, - bb: repr::BasicBlock, + bb: mir::BasicBlock, statements_len: usize) { let (mir, move_data) = (self.mir, &ctxt.move_data); @@ -481,9 +481,9 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> { fn propagate_call_return(&self, ctxt: &Self::Ctxt, in_out: &mut IdxSet<MoveOutIndex>, - _call_bb: repr::BasicBlock, - _dest_bb: repr::BasicBlock, - dest_lval: &repr::Lvalue) { + _call_bb: mir::BasicBlock, + _dest_bb: mir::BasicBlock, + dest_lval: &mir::Lvalue) { let move_data = &ctxt.move_data; let bits_per_block = self.bits_per_block(ctxt); diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs b/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs index 0c510e95b67..51817afbfea 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs @@ -13,7 +13,7 @@ use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::bitslice::{bitwise, BitwiseOperator}; use rustc::ty::TyCtxt; -use rustc::mir::repr::{self, Mir}; +use rustc::mir::{self, Mir}; use std::fmt::Debug; use std::io; @@ -78,14 +78,12 @@ impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> // the kill-sets. { - let sets = &mut self.flow_state.sets.for_block(repr::START_BLOCK.index()); + let sets = &mut self.flow_state.sets.for_block(mir::START_BLOCK.index()); self.flow_state.operator.start_block_effect(&self.ctxt, sets); } for (bb, data) in self.mir.basic_blocks().iter_enumerated() { - let &repr::BasicBlockData { ref statements, - ref terminator, - is_cleanup: _ } = data; + let &mir::BasicBlockData { ref statements, ref terminator, is_cleanup: _ } = data; let sets = &mut self.flow_state.sets.for_block(bb.index()); for j_stmt in 0..statements.len() { @@ -122,7 +120,7 @@ impl<'b, 'a: 'b, 'tcx: 'a, BD> PropagationContext<'b, 'a, 'tcx, BD> in_out.subtract(sets.kill_set); } builder.propagate_bits_into_graph_successors_of( - in_out, &mut self.changed, (repr::BasicBlock::new(bb_idx), bb_data)); + in_out, &mut self.changed, (mir::BasicBlock::new(bb_idx), bb_data)); } } } @@ -336,7 +334,7 @@ pub trait BitDenotation { fn statement_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<Self::Idx>, - bb: repr::BasicBlock, + bb: mir::BasicBlock, idx_stmt: usize); /// Mutates the block-sets (the flow sets for the given @@ -352,7 +350,7 @@ pub trait BitDenotation { fn terminator_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<Self::Idx>, - bb: repr::BasicBlock, + bb: mir::BasicBlock, idx_term: usize); /// Mutates the block-sets according to the (flow-dependent) @@ -377,9 +375,9 @@ pub trait BitDenotation { fn propagate_call_return(&self, ctxt: &Self::Ctxt, in_out: &mut IdxSet<Self::Idx>, - call_bb: repr::BasicBlock, - dest_bb: repr::BasicBlock, - dest_lval: &repr::Lvalue); + call_bb: mir::BasicBlock, + dest_bb: mir::BasicBlock, + dest_lval: &mir::Lvalue); } impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> @@ -444,39 +442,39 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> &mut self, in_out: &mut IdxSet<D::Idx>, changed: &mut bool, - (bb, bb_data): (repr::BasicBlock, &repr::BasicBlockData)) + (bb, bb_data): (mir::BasicBlock, &mir::BasicBlockData)) { match bb_data.terminator().kind { - repr::TerminatorKind::Return | - repr::TerminatorKind::Resume | - repr::TerminatorKind::Unreachable => {} - repr::TerminatorKind::Goto { ref target } | - repr::TerminatorKind::Assert { ref target, cleanup: None, .. } | - repr::TerminatorKind::Drop { ref target, location: _, unwind: None } | - repr::TerminatorKind::DropAndReplace { + mir::TerminatorKind::Return | + mir::TerminatorKind::Resume | + mir::TerminatorKind::Unreachable => {} + mir::TerminatorKind::Goto { ref target } | + mir::TerminatorKind::Assert { ref target, cleanup: None, .. } | + mir::TerminatorKind::Drop { ref target, location: _, unwind: None } | + mir::TerminatorKind::DropAndReplace { ref target, value: _, location: _, unwind: None } => { self.propagate_bits_into_entry_set_for(in_out, changed, target); } - repr::TerminatorKind::Assert { ref target, cleanup: Some(ref unwind), .. } | - repr::TerminatorKind::Drop { ref target, location: _, unwind: Some(ref unwind) } | - repr::TerminatorKind::DropAndReplace { + mir::TerminatorKind::Assert { ref target, cleanup: Some(ref unwind), .. } | + mir::TerminatorKind::Drop { ref target, location: _, unwind: Some(ref unwind) } | + mir::TerminatorKind::DropAndReplace { ref target, value: _, location: _, unwind: Some(ref unwind) } => { self.propagate_bits_into_entry_set_for(in_out, changed, target); self.propagate_bits_into_entry_set_for(in_out, changed, unwind); } - repr::TerminatorKind::If { ref targets, .. } => { + mir::TerminatorKind::If { ref targets, .. } => { self.propagate_bits_into_entry_set_for(in_out, changed, &targets.0); self.propagate_bits_into_entry_set_for(in_out, changed, &targets.1); } - repr::TerminatorKind::Switch { ref targets, .. } | - repr::TerminatorKind::SwitchInt { ref targets, .. } => { + mir::TerminatorKind::Switch { ref targets, .. } | + mir::TerminatorKind::SwitchInt { ref targets, .. } => { for target in targets { self.propagate_bits_into_entry_set_for(in_out, changed, target); } } - repr::TerminatorKind::Call { ref cleanup, ref destination, func: _, args: _ } => { + mir::TerminatorKind::Call { ref cleanup, ref destination, func: _, args: _ } => { if let Some(ref unwind) = *cleanup { self.propagate_bits_into_entry_set_for(in_out, changed, unwind); } @@ -494,7 +492,7 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> fn propagate_bits_into_entry_set_for(&mut self, in_out: &IdxSet<D::Idx>, changed: &mut bool, - bb: &repr::BasicBlock) { + bb: &mir::BasicBlock) { let entry_set = self.flow_state.sets.for_block(bb.index()).on_entry; let set_changed = bitwise(entry_set.words_mut(), in_out.words(), diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs index 5e22d477c51..b8c26a0512f 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs @@ -13,7 +13,7 @@ use syntax::ast; use syntax_pos::Span; use rustc::ty::{self, TyCtxt}; -use rustc::mir::repr::{self, Mir}; +use rustc::mir::{self, Mir}; use rustc_data_structures::indexed_vec::Idx; use super::super::gather_moves::{MovePathIndex, LookupResult}; @@ -59,13 +59,11 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &Mir<'tcx>, ctxt: &O::Ctxt, results: &DataflowResults<O>, - bb: repr::BasicBlock) where + bb: mir::BasicBlock) where O: BitDenotation<Ctxt=MoveDataParamEnv<'tcx>, Idx=MovePathIndex> { let move_data = &ctxt.move_data; - let repr::BasicBlockData { ref statements, - ref terminator, - is_cleanup: _ } = mir[bb]; + let mir::BasicBlockData { ref statements, ref terminator, is_cleanup: _ } = mir[bb]; let (args, span) = match is_rustc_peek(tcx, terminator) { Some(args_and_span) => args_and_span, @@ -73,7 +71,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; assert!(args.len() == 1); let peek_arg_lval = match args[0] { - repr::Operand::Consume(ref lval @ repr::Lvalue::Local(_)) => Some(lval), + mir::Operand::Consume(ref lval @ mir::Lvalue::Local(_)) => Some(lval), _ => None, }; @@ -103,21 +101,19 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, for (j, stmt) in statements.iter().enumerate() { debug!("rustc_peek: ({:?},{}) {:?}", bb, j, stmt); let (lvalue, rvalue) = match stmt.kind { - repr::StatementKind::Assign(ref lvalue, ref rvalue) => { + mir::StatementKind::Assign(ref lvalue, ref rvalue) => { (lvalue, rvalue) } - repr::StatementKind::StorageLive(_) | - repr::StatementKind::StorageDead(_) | - repr::StatementKind::Nop => continue, - repr::StatementKind::SetDiscriminant{ .. } => + mir::StatementKind::StorageLive(_) | + mir::StatementKind::StorageDead(_) | + mir::StatementKind::Nop => continue, + mir::StatementKind::SetDiscriminant{ .. } => span_bug!(stmt.source_info.span, "sanity_check should run before Deaggregator inserts SetDiscriminant"), }; if lvalue == peek_arg_lval { - if let repr::Rvalue::Ref(_, - repr::BorrowKind::Shared, - ref peeking_at_lval) = *rvalue { + if let mir::Rvalue::Ref(_, mir::BorrowKind::Shared, ref peeking_at_lval) = *rvalue { // Okay, our search is over. match move_data.rev_lookup.find(peeking_at_lval) { LookupResult::Exact(peek_mpi) => { @@ -162,12 +158,12 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } fn is_rustc_peek<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - terminator: &'a Option<repr::Terminator<'tcx>>) - -> Option<(&'a [repr::Operand<'tcx>], Span)> { - if let Some(repr::Terminator { ref kind, source_info, .. }) = *terminator { - if let repr::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind + terminator: &'a Option<mir::Terminator<'tcx>>) + -> Option<(&'a [mir::Operand<'tcx>], Span)> { + if let Some(mir::Terminator { ref kind, source_info, .. }) = *terminator { + if let mir::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind { - if let repr::Operand::Constant(ref func) = *oper + if let mir::Operand::Constant(ref func) = *oper { if let ty::TyFnDef(def_id, _, &ty::BareFnTy { abi, .. }) = func.ty.sty { diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs index fce5553c2fe..191cd981b61 100644 --- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs +++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs @@ -17,7 +17,7 @@ use super::{DropFlagState, MoveDataParamEnv}; use super::patch::MirPatch; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::subst::{Kind, Subst, Substs}; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc::mir::transform::{Pass, MirPass, MirSource}; use rustc::middle::const_val::ConstVal; use rustc::middle::lang_items; diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs index 16e25d2b772..1dc5769e63c 100644 --- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs @@ -10,7 +10,7 @@ use rustc::ty::{self, TyCtxt, ParameterEnvironment}; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc::util::nodemap::FnvHashMap; use rustc_data_structures::indexed_vec::{IndexVec}; diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs index 2a3c602b134..cea9170da9f 100644 --- a/src/librustc_borrowck/borrowck/mir/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/mod.rs @@ -17,8 +17,7 @@ use syntax_pos::{Span, DUMMY_SP}; use rustc::hir; use rustc::hir::intravisit::{FnKind}; -use rustc::mir::repr; -use rustc::mir::repr::{BasicBlock, BasicBlockData, Mir, Statement, Terminator, Location}; +use rustc::mir::{self, BasicBlock, BasicBlockData, Mir, Statement, Terminator, Location}; use rustc::session::Session; use rustc::ty::{self, TyCtxt}; @@ -56,15 +55,13 @@ pub struct MoveDataParamEnv<'tcx> { param_env: ty::ParameterEnvironment<'tcx>, } -pub fn borrowck_mir<'a, 'tcx: 'a>( - bcx: &mut BorrowckCtxt<'a, 'tcx>, - fk: FnKind, - _decl: &hir::FnDecl, - mir: &'a Mir<'tcx>, - body: &hir::Block, - _sp: Span, - id: ast::NodeId, - attributes: &[ast::Attribute]) { +pub fn borrowck_mir(bcx: &mut BorrowckCtxt, + fk: FnKind, + _decl: &hir::FnDecl, + body: &hir::Block, + _sp: Span, + id: ast::NodeId, + attributes: &[ast::Attribute]) { match fk { FnKind::ItemFn(name, ..) | FnKind::Method(name, ..) => { @@ -76,8 +73,10 @@ pub fn borrowck_mir<'a, 'tcx: 'a>( } let tcx = bcx.tcx; - let param_env = ty::ParameterEnvironment::for_item(tcx, id); + + let mir = &tcx.item_mir(tcx.map.local_def_id(id)); + let move_data = MoveData::gather_moves(mir, tcx, ¶m_env); let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env }; let flow_inits = @@ -171,8 +170,8 @@ pub struct MirBorrowckCtxt<'b, 'a: 'b, 'tcx: 'a> { mir: &'b Mir<'tcx>, node_id: ast::NodeId, move_data: MoveData<'tcx>, - flow_inits: DataflowResults<MaybeInitializedLvals<'a, 'tcx>>, - flow_uninits: DataflowResults<MaybeUninitializedLvals<'a, 'tcx>> + flow_inits: DataflowResults<MaybeInitializedLvals<'b, 'tcx>>, + flow_uninits: DataflowResults<MaybeUninitializedLvals<'b, 'tcx>> } impl<'b, 'a: 'b, 'tcx: 'a> MirBorrowckCtxt<'b, 'a, 'tcx> { @@ -214,12 +213,12 @@ fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>, path: MovePathIndex, mut cond: F) -> Option<MovePathIndex> - where F: FnMut(&repr::LvalueProjection<'tcx>) -> bool + where F: FnMut(&mir::LvalueProjection<'tcx>) -> bool { let mut next_child = move_data.move_paths[path].first_child; while let Some(child_index) = next_child { match move_data.move_paths[child_index].lvalue { - repr::Lvalue::Projection(ref proj) => { + mir::Lvalue::Projection(ref proj) => { if cond(proj) { return Some(child_index) } @@ -252,7 +251,7 @@ fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>, /// FIXME: we have to do something for moving slice patterns. fn lvalue_contents_drop_state_cannot_differ<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &Mir<'tcx>, - lv: &repr::Lvalue<'tcx>) -> bool { + lv: &mir::Lvalue<'tcx>) -> bool { let ty = lv.ty(mir, tcx).to_ty(tcx); match ty.sty { ty::TyArray(..) | ty::TySlice(..) | ty::TyRef(..) | ty::TyRawPtr(..) => { @@ -339,7 +338,7 @@ fn drop_flag_effects_for_function_entry<'a, 'tcx, F>( { let move_data = &ctxt.move_data; for arg in mir.args_iter() { - let lvalue = repr::Lvalue::Local(arg); + let lvalue = mir::Lvalue::Local(arg); let lookup_result = move_data.rev_lookup.find(&lvalue); on_lookup_result_bits(tcx, mir, move_data, lookup_result, @@ -379,23 +378,23 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>( let block = &mir[loc.block]; match block.statements.get(loc.statement_index) { Some(stmt) => match stmt.kind { - repr::StatementKind::SetDiscriminant{ .. } => { + mir::StatementKind::SetDiscriminant{ .. } => { span_bug!(stmt.source_info.span, "SetDiscrimant should not exist during borrowck"); } - repr::StatementKind::Assign(ref lvalue, _) => { + mir::StatementKind::Assign(ref lvalue, _) => { debug!("drop_flag_effects: assignment {:?}", stmt); on_lookup_result_bits(tcx, mir, move_data, move_data.rev_lookup.find(lvalue), |moi| callback(moi, DropFlagState::Present)) } - repr::StatementKind::StorageLive(_) | - repr::StatementKind::StorageDead(_) | - repr::StatementKind::Nop => {} + mir::StatementKind::StorageLive(_) | + mir::StatementKind::StorageDead(_) | + mir::StatementKind::Nop => {} }, None => { debug!("drop_flag_effects: replace {:?}", block.terminator()); match block.terminator().kind { - repr::TerminatorKind::DropAndReplace { ref location, .. } => { + mir::TerminatorKind::DropAndReplace { ref location, .. } => { on_lookup_result_bits(tcx, mir, move_data, move_data.rev_lookup.find(location), |moi| callback(moi, DropFlagState::Present)) diff --git a/src/librustc_borrowck/borrowck/mir/patch.rs b/src/librustc_borrowck/borrowck/mir/patch.rs index 5d018c98684..19f240da730 100644 --- a/src/librustc_borrowck/borrowck/mir/patch.rs +++ b/src/librustc_borrowck/borrowck/mir/patch.rs @@ -9,7 +9,7 @@ // except according to those terms. use rustc::ty::Ty; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; /// This struct represents a patch to MIR, which can add diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 89b12e76c3c..ef6936b6e7d 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -51,8 +51,6 @@ use rustc::hir::{FnDecl, Block}; use rustc::hir::intravisit; use rustc::hir::intravisit::{Visitor, FnKind}; -use rustc::mir::mir_map::MirMap; - pub mod check_loans; pub mod gather_loans; @@ -102,10 +100,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> { } } -pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &MirMap<'tcx>) { +pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { let mut bccx = BorrowckCtxt { tcx: tcx, - mir_map: Some(mir_map), free_region_map: FreeRegionMap::new(), stats: BorrowStats { loaned_paths_same: 0, @@ -168,12 +165,9 @@ fn borrowck_fn(this: &mut BorrowckCtxt, attributes: &[ast::Attribute]) { debug!("borrowck_fn(id={})", id); - let def_id = this.tcx.map.local_def_id(id); - if attributes.iter().any(|item| item.check_name("rustc_mir_borrowck")) { - let mir = this.mir_map.unwrap().map.get(&def_id).unwrap(); this.with_temp_region_map(id, |this| { - mir::borrowck_mir(this, fk, decl, mir, body, sp, id, attributes) + mir::borrowck_mir(this, fk, decl, body, sp, id, attributes) }); } @@ -249,7 +243,6 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, /// the `BorrowckCtxt` itself , e.g. the flowgraph visualizer. pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, - mir_map: Option<&'a MirMap<'tcx>>, fn_parts: FnParts<'a>, cfg: &cfg::CFG) -> (BorrowckCtxt<'a, 'tcx>, AnalysisData<'a, 'tcx>) @@ -257,7 +250,6 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>( let mut bccx = BorrowckCtxt { tcx: tcx, - mir_map: mir_map, free_region_map: FreeRegionMap::new(), stats: BorrowStats { loaned_paths_same: 0, @@ -297,10 +289,7 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> { free_region_map: FreeRegionMap, // Statistics: - stats: BorrowStats, - - // NodeId to MIR mapping (for methods that carry the #[rustc_mir] attribute). - mir_map: Option<&'a MirMap<'tcx>>, + stats: BorrowStats } #[derive(Clone)] diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index a6c886533c8..946a3974747 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -11,7 +11,7 @@ use eval; use rustc::middle::const_val::ConstVal; -use rustc::mir::repr::{Field, BorrowKind, Mutability}; +use rustc::mir::{Field, BorrowKind, Mutability}; use rustc::ty::{self, TyCtxt, AdtDef, Ty, Region}; use rustc::hir::{self, PatKind}; use rustc::hir::def::Def; @@ -436,7 +436,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { } Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) | - Def::TyAlias(..) | Def::AssociatedTy(..) => { + Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => { PatternKind::Leaf { subpatterns: subpatterns } } diff --git a/src/librustc_data_structures/blake2b.rs b/src/librustc_data_structures/blake2b.rs index 996df2e7fcf..8c82c135dc4 100644 --- a/src/librustc_data_structures/blake2b.rs +++ b/src/librustc_data_structures/blake2b.rs @@ -20,17 +20,25 @@ // implementation. If you have the luxury of being able to use crates from // crates.io, you can go there and find still faster implementations. +use std::mem; +use std::slice; + pub struct Blake2bCtx { b: [u8; 128], h: [u64; 8], t: [u64; 2], c: usize, - outlen: usize, + outlen: u16, + finalized: bool } impl ::std::fmt::Debug for Blake2bCtx { fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - write!(fmt, "{:?}", self.h) + try!(write!(fmt, "hash: ")); + for v in &self.h[..] { + try!(write!(fmt, "{:x}", v)); + } + Ok(()) } } @@ -136,7 +144,7 @@ fn blake2b_compress(ctx: &mut Blake2bCtx, last: bool) { } } -pub fn blake2b_new(outlen: usize, key: &[u8]) -> Blake2bCtx { +fn blake2b_new(outlen: usize, key: &[u8]) -> Blake2bCtx { assert!(outlen > 0 && outlen <= 64 && key.len() <= 64); let mut ctx = Blake2bCtx { @@ -144,7 +152,8 @@ pub fn blake2b_new(outlen: usize, key: &[u8]) -> Blake2bCtx { h: BLAKE2B_IV, t: [0; 2], c: 0, - outlen: outlen, + outlen: outlen as u16, + finalized: false, }; ctx.h[0] ^= 0x01010000 ^ ((key.len() << 8) as u64) ^ (outlen as u64); @@ -157,8 +166,9 @@ pub fn blake2b_new(outlen: usize, key: &[u8]) -> Blake2bCtx { ctx } -pub fn blake2b_update(ctx: &mut Blake2bCtx, mut data: &[u8]) -{ +fn blake2b_update(ctx: &mut Blake2bCtx, mut data: &[u8]) { + assert!(!ctx.finalized, "Blake2bCtx already finalized"); + let mut bytes_to_copy = data.len(); let mut space_in_buffer = ctx.b.len() - ctx.c; @@ -183,8 +193,10 @@ pub fn blake2b_update(ctx: &mut Blake2bCtx, mut data: &[u8]) } } -pub fn blake2b_final(mut ctx: Blake2bCtx, out: &mut [u8]) +fn blake2b_final(ctx: &mut Blake2bCtx) { + assert!(!ctx.finalized, "Blake2bCtx already finalized"); + ctx.t[0] = ctx.t[0].wrapping_add(ctx.c as u64); if ctx.t[0] < ctx.c as u64 { ctx.t[1] += 1; @@ -195,7 +207,7 @@ pub fn blake2b_final(mut ctx: Blake2bCtx, out: &mut [u8]) ctx.c += 1; } - blake2b_compress(&mut ctx, true); + blake2b_compress(ctx, true); if cfg!(target_endian = "big") { // Make sure that the data is in memory in little endian format, as is @@ -205,13 +217,13 @@ pub fn blake2b_final(mut ctx: Blake2bCtx, out: &mut [u8]) } } - checked_mem_copy(&ctx.h, out, ctx.outlen); + ctx.finalized = true; } #[inline(always)] fn checked_mem_copy<T1, T2>(from: &[T1], to: &mut [T2], byte_count: usize) { - let from_size = from.len() * ::std::mem::size_of::<T1>(); - let to_size = to.len() * ::std::mem::size_of::<T2>(); + let from_size = from.len() * mem::size_of::<T1>(); + let to_size = to.len() * mem::size_of::<T2>(); assert!(from_size >= byte_count); assert!(to_size >= byte_count); let from_byte_ptr = from.as_ptr() as * const u8; @@ -225,7 +237,45 @@ pub fn blake2b(out: &mut [u8], key: &[u8], data: &[u8]) { let mut ctx = blake2b_new(out.len(), key); blake2b_update(&mut ctx, data); - blake2b_final(ctx, out); + blake2b_final(&mut ctx); + checked_mem_copy(&ctx.h, out, ctx.outlen as usize); +} + +pub struct Blake2bHasher(Blake2bCtx); + +impl ::std::hash::Hasher for Blake2bHasher { + fn write(&mut self, bytes: &[u8]) { + blake2b_update(&mut self.0, bytes); + } + + fn finish(&self) -> u64 { + assert!(self.0.outlen == 8, + "Hasher initialized with incompatible output length"); + u64::from_le(self.0.h[0]) + } +} + +impl Blake2bHasher { + pub fn new(outlen: usize, key: &[u8]) -> Blake2bHasher { + Blake2bHasher(blake2b_new(outlen, key)) + } + + pub fn finalize(&mut self) -> &[u8] { + if !self.0.finalized { + blake2b_final(&mut self.0); + } + debug_assert!(mem::size_of_val(&self.0.h) >= self.0.outlen as usize); + let raw_ptr = (&self.0.h[..]).as_ptr() as * const u8; + unsafe { + slice::from_raw_parts(raw_ptr, self.0.outlen as usize) + } + } +} + +impl ::std::fmt::Debug for Blake2bHasher { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { + write!(fmt, "{:?}", self.0) + } } #[cfg(test)] @@ -245,6 +295,8 @@ fn selftest_seq(out: &mut [u8], seed: u32) #[test] fn blake2b_selftest() { + use std::hash::Hasher; + // grand hash of hash results const BLAKE2B_RES: [u8; 32] = [ 0xC2, 0x3A, 0x78, 0x00, 0xD9, 0x81, 0x23, 0xBD, @@ -261,7 +313,7 @@ fn blake2b_selftest() let mut md = [0u8; 64]; let mut key = [0u8; 64]; - let mut ctx = blake2b_new(32, &[]); + let mut hasher = Blake2bHasher::new(32, &[]); for i in 0 .. 4 { let outlen = B2B_MD_LEN[i]; @@ -270,16 +322,16 @@ fn blake2b_selftest() selftest_seq(&mut data[.. inlen], inlen as u32); // unkeyed hash blake2b(&mut md[.. outlen], &[], &data[.. inlen]); - blake2b_update(&mut ctx, &md[.. outlen]); // hash the hash + hasher.write(&md[.. outlen]); // hash the hash selftest_seq(&mut key[0 .. outlen], outlen as u32); // keyed hash blake2b(&mut md[.. outlen], &key[.. outlen], &data[.. inlen]); - blake2b_update(&mut ctx, &md[.. outlen]); // hash the hash + hasher.write(&md[.. outlen]); // hash the hash } } // compute and compare the hash of hashes - blake2b_final(ctx, &mut md[..]); + let md = hasher.finalize(); for i in 0 .. 32 { assert_eq!(md[i], BLAKE2B_RES[i]); } diff --git a/src/librustc_data_structures/fmt_wrap.rs b/src/librustc_data_structures/fmt_wrap.rs new file mode 100644 index 00000000000..50fd1d802b7 --- /dev/null +++ b/src/librustc_data_structures/fmt_wrap.rs @@ -0,0 +1,31 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fmt; + +// Provide some more formatting options for some data types (at the moment +// that's just `{:x}` for slices of u8). + +pub struct FmtWrap<T>(pub T); + +impl<'a> fmt::LowerHex for FmtWrap<&'a [u8]> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + for byte in self.0.iter() { + try!(write!(formatter, "{:02x}", byte)); + } + Ok(()) + } +} + +#[test] +fn test_lower_hex() { + let bytes: &[u8] = &[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]; + assert_eq!("0123456789abcdef", &format!("{:x}", FmtWrap(bytes))); +} diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 143c180f823..fc963dac949 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -49,6 +49,7 @@ pub mod accumulate_vec; pub mod bitslice; pub mod blake2b; pub mod bitvec; +pub mod fmt_wrap; pub mod graph; pub mod ivar; pub mod indexed_set; diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 98e2aa88189..99d3e155e89 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -18,6 +18,7 @@ rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_borrowck = { path = "../librustc_borrowck" } rustc_const_eval = { path = "../librustc_const_eval" } +rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_incremental = { path = "../librustc_incremental" } rustc_lint = { path = "../librustc_lint" } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 9b27f7a29e9..da1d5ad2c4a 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -12,8 +12,10 @@ use rustc::hir; use rustc::hir::{map as hir_map, FreevarMap, TraitMap}; use rustc::hir::def::DefMap; use rustc::hir::lowering::lower_crate; +use rustc_data_structures::blake2b::Blake2bHasher; +use rustc_data_structures::fmt_wrap::FmtWrap; +use rustc::ty::util::ArchIndependentHasher; use rustc_mir as mir; -use rustc::mir::mir_map::MirMap; use rustc::session::{Session, CompileResult, compile_result_from_err_count}; use rustc::session::config::{self, Input, OutputFilenames, OutputType, OutputTypes}; @@ -24,7 +26,6 @@ use rustc::middle::privacy::AccessLevels; use rustc::ty::{self, TyCtxt}; use rustc::util::common::time; use rustc::util::nodemap::NodeSet; -use rustc_back::sha2::{Sha256, Digest}; use rustc_borrowck as borrowck; use rustc_incremental::{self, IncrementalHashesMap}; use rustc_resolve::{MakeGlobMap, Resolver}; @@ -68,7 +69,6 @@ pub struct Resolutions { pub fn compile_input(sess: &Session, cstore: &CStore, - cfg: ast::CrateConfig, input: &Input, outdir: &Option<PathBuf>, output: &Option<PathBuf>, @@ -92,7 +92,7 @@ pub fn compile_input(sess: &Session, // large chunks of memory alive and we want to free them as soon as // possible to keep the peak memory usage low let (outputs, trans) = { - let krate = match phase_1_parse_input(sess, cfg, input) { + let krate = match phase_1_parse_input(sess, input) { Ok(krate) => krate, Err(mut parse_error) => { parse_error.emit(); @@ -175,7 +175,7 @@ pub fn compile_input(sess: &Session, resolutions, &arenas, &crate_name, - |tcx, mir_map, analysis, incremental_hashes_map, result| { + |tcx, analysis, incremental_hashes_map, result| { { // Eventually, we will want to track plugins. let _ignore = tcx.dep_graph.in_ignore(); @@ -187,7 +187,6 @@ pub fn compile_input(sess: &Session, opt_crate, tcx.map.krate(), &analysis, - mir_map.as_ref(), tcx, &crate_name); (control.after_analysis.callback)(&mut state); @@ -203,10 +202,7 @@ pub fn compile_input(sess: &Session, println!("Pre-trans"); tcx.print_debug_stats(); } - let trans = phase_4_translate_to_llvm(tcx, - mir_map.unwrap(), - analysis, - &incremental_hashes_map); + let trans = phase_4_translate_to_llvm(tcx, analysis, &incremental_hashes_map); if log_enabled!(::log::INFO) { println!("Post-trans"); @@ -348,7 +344,6 @@ pub struct CompileState<'a, 'b, 'ast: 'a, 'tcx: 'b> where 'ast: 'tcx { pub hir_crate: Option<&'a hir::Crate>, pub ast_map: Option<&'a hir_map::Map<'ast>>, pub resolutions: Option<&'a Resolutions>, - pub mir_map: Option<&'b MirMap<'tcx>>, pub analysis: Option<&'a ty::CrateAnalysis<'a>>, pub tcx: Option<TyCtxt<'b, 'tcx, 'tcx>>, pub trans: Option<&'a trans::CrateTranslation>, @@ -375,7 +370,6 @@ impl<'a, 'b, 'ast, 'tcx> CompileState<'a, 'b, 'ast, 'tcx> { ast_map: None, resolutions: None, analysis: None, - mir_map: None, tcx: None, trans: None, } @@ -449,13 +443,11 @@ impl<'a, 'b, 'ast, 'tcx> CompileState<'a, 'b, 'ast, 'tcx> { krate: Option<&'a ast::Crate>, hir_crate: &'a hir::Crate, analysis: &'a ty::CrateAnalysis<'a>, - mir_map: Option<&'b MirMap<'tcx>>, tcx: TyCtxt<'b, 'tcx, 'tcx>, crate_name: &'a str) -> CompileState<'a, 'b, 'ast, 'tcx> { CompileState { analysis: Some(analysis), - mir_map: mir_map, tcx: Some(tcx), expanded_crate: krate, hir_crate: Some(hir_crate), @@ -491,23 +483,17 @@ impl<'a, 'b, 'ast, 'tcx> CompileState<'a, 'b, 'ast, 'tcx> { } } -pub fn phase_1_parse_input<'a>(sess: &'a Session, - cfg: ast::CrateConfig, - input: &Input) - -> PResult<'a, ast::Crate> { +pub fn phase_1_parse_input<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> { let continue_after_error = sess.opts.debugging_opts.continue_parse_after_error; sess.diagnostic().set_continue_after_error(continue_after_error); let krate = time(sess.time_passes(), "parsing", || { match *input { Input::File(ref file) => { - parse::parse_crate_from_file(file, cfg.clone(), &sess.parse_sess) + parse::parse_crate_from_file(file, &sess.parse_sess) } Input::Str { ref input, ref name } => { - parse::parse_crate_from_source_str(name.clone(), - input.clone(), - cfg.clone(), - &sess.parse_sess) + parse::parse_crate_from_source_str(name.clone(), input.clone(), &sess.parse_sess) } } })?; @@ -645,7 +631,7 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session, // its contents but the results of name resolution on those contents. Hopefully we'll push // this back at some point. let _ignore = sess.dep_graph.in_ignore(); - let mut crate_loader = CrateLoader::new(sess, &cstore, crate_name, krate.config.clone()); + let mut crate_loader = CrateLoader::new(sess, &cstore, crate_name); crate_loader.preprocess(&krate); let resolver_arenas = Resolver::arenas(); let mut resolver = @@ -686,7 +672,7 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session, should_test: sess.opts.test, ..syntax::ext::expand::ExpansionConfig::default(crate_name.to_string()) }; - let mut ecx = ExtCtxt::new(&sess.parse_sess, krate.config.clone(), cfg, &mut resolver); + let mut ecx = ExtCtxt::new(&sess.parse_sess, cfg, &mut resolver); let err_count = ecx.parse_sess.span_diagnostic.err_count(); let krate = ecx.monotonic_expander().expand_crate(krate); @@ -812,17 +798,16 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, f: F) -> Result<R, usize> where F: for<'a> FnOnce(TyCtxt<'a, 'tcx, 'tcx>, - Option<MirMap<'tcx>>, ty::CrateAnalysis, IncrementalHashesMap, CompileResult) -> R { macro_rules! try_with_f { - ($e: expr, ($t: expr, $m: expr, $a: expr, $h: expr)) => { + ($e: expr, ($t: expr, $a: expr, $h: expr)) => { match $e { Ok(x) => x, Err(x) => { - f($t, $m, $a, $h, Err(x)); + f($t, $a, $h, Err(x)); return Err(x); } } @@ -888,7 +873,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, || rustc_incremental::load_dep_graph(tcx, &incremental_hashes_map)); // passes are timed inside typeck - try_with_f!(typeck::check_crate(tcx), (tcx, None, analysis, incremental_hashes_map)); + try_with_f!(typeck::check_crate(tcx), (tcx, analysis, incremental_hashes_map)); time(time_passes, "const checking", @@ -928,28 +913,28 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, "rvalue checking", || rvalues::check_crate(tcx)); - let mut mir_map = - time(time_passes, - "MIR dump", - || mir::mir_map::build_mir_for_crate(tcx)); + time(time_passes, + "MIR dump", + || mir::mir_map::build_mir_for_crate(tcx)); time(time_passes, "MIR passes", || { let mut passes = sess.mir_passes.borrow_mut(); // Push all the built-in passes. passes.push_hook(box mir::transform::dump_mir::DumpMir); passes.push_pass(box mir::transform::simplify_cfg::SimplifyCfg::new("initial")); - passes.push_pass(box mir::transform::qualify_consts::QualifyAndPromoteConstants); + passes.push_pass( + box mir::transform::qualify_consts::QualifyAndPromoteConstants::default()); passes.push_pass(box mir::transform::type_check::TypeckMir); passes.push_pass( box mir::transform::simplify_branches::SimplifyBranches::new("initial")); passes.push_pass(box mir::transform::simplify_cfg::SimplifyCfg::new("qualify-consts")); // And run everything. - passes.run_passes(tcx, &mut mir_map); + passes.run_passes(tcx); }); time(time_passes, "borrow checking", - || borrowck::check_crate(tcx, &mir_map)); + || borrowck::check_crate(tcx)); // Avoid overwhelming user with errors if type checking failed. // I'm not sure how helpful this is, to be honest, but it avoids @@ -958,11 +943,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, // lint warnings and so on -- kindck used to do this abort, but // kindck is gone now). -nmatsakis if sess.err_count() > 0 { - return Ok(f(tcx, - Some(mir_map), - analysis, - incremental_hashes_map, - Err(sess.err_count()))); + return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count()))); } analysis.reachable = @@ -990,20 +971,15 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, // The above three passes generate errors w/o aborting if sess.err_count() > 0 { - return Ok(f(tcx, - Some(mir_map), - analysis, - incremental_hashes_map, - Err(sess.err_count()))); + return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count()))); } - Ok(f(tcx, Some(mir_map), analysis, incremental_hashes_map, Ok(()))) + Ok(f(tcx, analysis, incremental_hashes_map, Ok(()))) }) } /// Run the translation phase to LLVM, after which the AST and analysis can pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - mut mir_map: MirMap<'tcx>, analysis: ty::CrateAnalysis, incremental_hashes_map: &IncrementalHashesMap) -> trans::CrateTranslation { @@ -1037,13 +1013,13 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, passes.push_pass(box mir::transform::add_call_guards::AddCallGuards); passes.push_pass(box mir::transform::dump_mir::Marker("PreTrans")); - passes.run_passes(tcx, &mut mir_map); + passes.run_passes(tcx); }); let translation = time(time_passes, "translation", - move || trans::trans_crate(tcx, &mir_map, analysis, &incremental_hashes_map)); + move || trans::trans_crate(tcx, analysis, &incremental_hashes_map)); time(time_passes, "assert dep graph", @@ -1247,7 +1223,16 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c } pub fn compute_crate_disambiguator(session: &Session) -> String { - let mut hasher = Sha256::new(); + use std::hash::Hasher; + + // The crate_disambiguator is a 128 bit hash. The disambiguator is fed + // into various other hashes quite a bit (symbol hashes, incr. comp. hashes, + // debuginfo type IDs, etc), so we don't want it to be too wide. 128 bits + // should still be safe enough to avoid collisions in practice. + // FIXME(mw): It seems that the crate_disambiguator is used everywhere as + // a hex-string instead of raw bytes. We should really use the + // smaller representation. + let mut hasher = ArchIndependentHasher::new(Blake2bHasher::new(128 / 8, &[])); let mut metadata = session.opts.cg.metadata.clone(); // We don't want the crate_disambiguator to dependent on the order @@ -1256,24 +1241,23 @@ pub fn compute_crate_disambiguator(session: &Session) -> String { // Every distinct -C metadata value is only incorporated once: metadata.dedup(); - hasher.input_str("metadata"); + hasher.write(b"metadata"); for s in &metadata { // Also incorporate the length of a metadata string, so that we generate // different values for `-Cmetadata=ab -Cmetadata=c` and // `-Cmetadata=a -Cmetadata=bc` - hasher.input_str(&format!("{}", s.len())[..]); - hasher.input_str(&s[..]); + hasher.write_usize(s.len()); + hasher.write(s.as_bytes()); } - let mut hash = hasher.result_str(); + let mut hash_state = hasher.into_inner(); + let hash_bytes = hash_state.finalize(); // If this is an executable, add a special suffix, so that we don't get // symbol conflicts when linking against a library of the same name. - if session.crate_types.borrow().contains(&config::CrateTypeExecutable) { - hash.push_str("-exe"); - } + let is_exe = session.crate_types.borrow().contains(&config::CrateTypeExecutable); - hash + format!("{:x}{}", FmtWrap(hash_bytes), if is_exe { "-exe" } else {""}) } pub fn build_output_filenames(input: &Input, diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index cb001688da2..cb78baa12a6 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -42,6 +42,7 @@ extern crate rustc; extern crate rustc_back; extern crate rustc_borrowck; extern crate rustc_const_eval; +extern crate rustc_data_structures; extern crate rustc_errors as errors; extern crate rustc_passes; extern crate rustc_lint; @@ -205,24 +206,20 @@ pub fn run_compiler<'a>(args: &[String], let loader = file_loader.unwrap_or(box RealFileLoader); let codemap = Rc::new(CodeMap::with_file_loader(loader)); - let sess = session::build_session_with_codemap(sopts, - &dep_graph, - input_file_path, - descriptions, - cstore.clone(), - codemap, - emitter_dest); + let mut sess = session::build_session_with_codemap( + sopts, &dep_graph, input_file_path, descriptions, cstore.clone(), codemap, emitter_dest, + ); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); + let mut cfg = config::build_configuration(&sess, cfg); target_features::add_configuration(&mut cfg, &sess); + sess.parse_sess.config = cfg; - do_or_return!(callbacks.late_callback(&matches, &sess, &cfg, &input, &odir, &ofile), - Some(sess)); + do_or_return!(callbacks.late_callback(&matches, &sess, &input, &odir, &ofile), Some(sess)); let plugins = sess.opts.debugging_opts.extra_plugins.clone(); let control = callbacks.build_controller(&sess, &matches); - (driver::compile_input(&sess, &cstore, cfg, &input, &odir, &ofile, - Some(plugins), &control), + (driver::compile_input(&sess, &cstore, &input, &odir, &ofile, Some(plugins), &control), Some(sess)) } @@ -310,7 +307,6 @@ pub trait CompilerCalls<'a> { fn late_callback(&mut self, _: &getopts::Matches, _: &Session, - _: &ast::CrateConfig, _: &Input, _: &Option<PathBuf>, _: &Option<PathBuf>) @@ -439,7 +435,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { } let dep_graph = DepGraph::new(sopts.build_dep_graph()); let cstore = Rc::new(CStore::new(&dep_graph)); - let sess = build_session(sopts.clone(), + let mut sess = build_session(sopts.clone(), &dep_graph, None, descriptions.clone(), @@ -447,11 +443,10 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let mut cfg = config::build_configuration(&sess, cfg.clone()); target_features::add_configuration(&mut cfg, &sess); - let should_stop = RustcDefaultCalls::print_crate_info(&sess, - &cfg, - None, - odir, - ofile); + sess.parse_sess.config = cfg; + let should_stop = + RustcDefaultCalls::print_crate_info(&sess, None, odir, ofile); + if should_stop == Compilation::Stop { return None; } @@ -467,12 +462,11 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { fn late_callback(&mut self, matches: &getopts::Matches, sess: &Session, - cfg: &ast::CrateConfig, input: &Input, odir: &Option<PathBuf>, ofile: &Option<PathBuf>) -> Compilation { - RustcDefaultCalls::print_crate_info(sess, cfg, Some(input), odir, ofile) + RustcDefaultCalls::print_crate_info(sess, Some(input), odir, ofile) .and_then(|| RustcDefaultCalls::list_metadata(sess, matches, input)) } @@ -593,7 +587,6 @@ impl RustcDefaultCalls { fn print_crate_info(sess: &Session, - cfg: &ast::CrateConfig, input: Option<&Input>, odir: &Option<PathBuf>, ofile: &Option<PathBuf>) @@ -649,8 +642,8 @@ impl RustcDefaultCalls { let allow_unstable_cfg = UnstableFeatures::from_environment() .is_nightly_build(); - for cfg in cfg { - if !allow_unstable_cfg && GatedCfg::gate(&*cfg).is_some() { + for cfg in &sess.parse_sess.config { + if !allow_unstable_cfg && GatedCfg::gate(cfg).is_some() { continue; } @@ -1036,13 +1029,10 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> { fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, Vec<ast::Attribute>> { match *input { Input::File(ref ifile) => { - parse::parse_crate_attrs_from_file(ifile, Vec::new(), &sess.parse_sess) + parse::parse_crate_attrs_from_file(ifile, &sess.parse_sess) } Input::Str { ref name, ref input } => { - parse::parse_crate_attrs_from_source_str(name.clone(), - input.clone(), - Vec::new(), - &sess.parse_sess) + parse::parse_crate_attrs_from_source_str(name.clone(), input.clone(), &sess.parse_sess) } } } diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 215287f8439..10ff7dc89f9 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -52,8 +52,6 @@ use rustc::hir::map::{blocks, NodePrinter}; use rustc::hir; use rustc::hir::print as pprust_hir; -use rustc::mir::mir_map::MirMap; - #[derive(Copy, Clone, PartialEq, Debug)] pub enum PpSourceMode { PpmNormal, @@ -234,7 +232,7 @@ impl PpSourceMode { resolutions.clone(), arenas, id, - |tcx, _, _, _, _| { + |tcx, _, _, _| { let annotation = TypedAnnotation { tcx: tcx, }; @@ -695,7 +693,6 @@ impl fold::Folder for ReplaceBodyWithLoop { fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - mir_map: Option<&MirMap<'tcx>>, code: blocks::Code, mode: PpFlowGraphMode, mut out: W) @@ -725,7 +722,6 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>, blocks::FnLikeCode(fn_like) => { let (bccx, analysis_data) = borrowck::build_borrowck_dataflow_data_for_fn(tcx, - mir_map, fn_like.to_fn_parts(), &cfg); @@ -952,32 +948,28 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, resolutions.clone(), arenas, crate_name, - |tcx, mir_map, _, _, _| { + |tcx, _, _, _| { match ppm { PpmMir | PpmMirCFG => { - if let Some(mir_map) = mir_map { - if let Some(nodeid) = nodeid { - let def_id = tcx.map.local_def_id(nodeid); - match ppm { - PpmMir => write_mir_pretty(tcx, iter::once(def_id), &mir_map, &mut out), - PpmMirCFG => { - write_mir_graphviz(tcx, iter::once(def_id), &mir_map, &mut out) - } - _ => unreachable!(), - }?; - } else { - match ppm { - PpmMir => write_mir_pretty(tcx, - mir_map.map.keys().into_iter(), - &mir_map, - &mut out), - PpmMirCFG => write_mir_graphviz(tcx, - mir_map.map.keys().into_iter(), - &mir_map, - &mut out), - _ => unreachable!(), - }?; - } + if let Some(nodeid) = nodeid { + let def_id = tcx.map.local_def_id(nodeid); + match ppm { + PpmMir => write_mir_pretty(tcx, iter::once(def_id), &mut out), + PpmMirCFG => { + write_mir_graphviz(tcx, iter::once(def_id), &mut out) + } + _ => unreachable!(), + }?; + } else { + match ppm { + PpmMir => write_mir_pretty(tcx, + tcx.mir_map.borrow().keys().into_iter(), + &mut out), + PpmMirCFG => write_mir_graphviz(tcx, + tcx.mir_map.borrow().keys().into_iter(), + &mut out), + _ => unreachable!(), + }?; } Ok(()) } @@ -995,12 +987,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, let out: &mut Write = &mut out; - print_flowgraph(variants, - tcx, - mir_map.as_ref(), - code, - mode, - out) + print_flowgraph(variants, tcx, code, mode, out) } None => { let message = format!("--pretty=flowgraph needs block, fn, or method; got \ diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index c400610a688..50903c89a58 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -106,12 +106,11 @@ fn test_env<F>(source_string: &str, let sess = session::build_session_(options, &dep_graph, None, diagnostic_handler, Rc::new(CodeMap::new()), cstore.clone()); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); - let krate_config = Vec::new(); let input = config::Input::Str { name: driver::anon_src(), input: source_string.to_string(), }; - let krate = driver::phase_1_parse_input(&sess, krate_config, &input).unwrap(); + let krate = driver::phase_1_parse_input(&sess, &input).unwrap(); let driver::ExpansionResult { defs, resolutions, mut hir_forest, .. } = { driver::phase_2_configure_and_expand( &sess, &cstore, krate, None, "test", None, MakeGlobMap::No, |_| Ok(()), diff --git a/src/librustc_incremental/calculate_svh/hasher.rs b/src/librustc_incremental/calculate_svh/hasher.rs index d92a8d375e0..49683a81227 100644 --- a/src/librustc_incremental/calculate_svh/hasher.rs +++ b/src/librustc_incremental/calculate_svh/hasher.rs @@ -8,21 +8,22 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::hash::Hasher; use std::mem; -use rustc_data_structures::blake2b; +use rustc_data_structures::blake2b::Blake2bHasher; +use rustc::ty::util::ArchIndependentHasher; use ich::Fingerprint; #[derive(Debug)] pub struct IchHasher { - state: blake2b::Blake2bCtx, + state: ArchIndependentHasher<Blake2bHasher>, bytes_hashed: u64, } impl IchHasher { pub fn new() -> IchHasher { + let hash_size = mem::size_of::<Fingerprint>(); IchHasher { - state: blake2b::blake2b_new(mem::size_of::<Fingerprint>(), &[]), + state: ArchIndependentHasher::new(Blake2bHasher::new(hash_size, &[])), bytes_hashed: 0 } } @@ -33,40 +34,19 @@ impl IchHasher { pub fn finish(self) -> Fingerprint { let mut fingerprint = Fingerprint::zero(); - blake2b::blake2b_final(self.state, &mut fingerprint.0); + fingerprint.0.copy_from_slice(self.state.into_inner().finalize()); fingerprint } } -impl Hasher for IchHasher { +impl ::std::hash::Hasher for IchHasher { fn finish(&self) -> u64 { bug!("Use other finish() implementation to get the full 128-bit hash."); } #[inline] fn write(&mut self, bytes: &[u8]) { - blake2b::blake2b_update(&mut self.state, bytes); + self.state.write(bytes); self.bytes_hashed += bytes.len() as u64; } - - #[inline] - fn write_u16(&mut self, i: u16) { - self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i.to_le()) }) - } - - #[inline] - fn write_u32(&mut self, i: u32) { - self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i.to_le()) }) - } - - #[inline] - fn write_u64(&mut self, i: u64) { - self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i.to_le()) }) - } - - #[inline] - fn write_usize(&mut self, i: usize) { - // always hash as u64, so we don't depend on the size of `usize` - self.write_u64(i as u64); - } } diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 0418148ffc7..94478f6603a 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -264,7 +264,7 @@ impl<'a, 'tcx, 'm> DirtyCleanMetadataVisitor<'a, 'tcx, 'm> { /// flag called `foo`. fn check_config(tcx: TyCtxt, attr: &ast::Attribute) -> bool { debug!("check_config(attr={:?})", attr); - let config = &tcx.map.krate().config; + let config = &tcx.sess.parse_sess.config; debug!("check_config: config={:?}", config); for item in attr.meta_item_list().unwrap_or(&[]) { if item.check_name(CFG) { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index d191c82abed..6f114e09a6c 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -225,6 +225,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { id: LintId::of(SAFE_EXTERN_STATICS), reference: "issue #36247 <https://github.com/rust-lang/rust/issues/35112>", }, + FutureIncompatibleInfo { + id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY), + reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>", + }, ]); // Register renamed and removed lints diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index d160d29af7d..f4558a2871d 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -52,7 +52,6 @@ pub struct CrateLoader<'a> { next_crate_num: CrateNum, foreign_item_map: FnvHashMap<String, Vec<ast::NodeId>>, local_crate_name: String, - local_crate_config: ast::CrateConfig, } fn dump_crates(cstore: &CStore) { @@ -144,18 +143,13 @@ enum LoadResult { } impl<'a> CrateLoader<'a> { - pub fn new(sess: &'a Session, - cstore: &'a CStore, - local_crate_name: &str, - local_crate_config: ast::CrateConfig) - -> Self { + pub fn new(sess: &'a Session, cstore: &'a CStore, local_crate_name: &str) -> Self { CrateLoader { sess: sess, cstore: cstore, next_crate_num: cstore.next_crate_num(), foreign_item_map: FnvHashMap(), local_crate_name: local_crate_name.to_owned(), - local_crate_config: local_crate_config, } } @@ -541,7 +535,6 @@ impl<'a> CrateLoader<'a> { // NB: Don't use parse::parse_tts_from_source_str because it parses with // quote_depth > 0. let mut p = parse::new_parser_from_source_str(&self.sess.parse_sess, - self.local_crate_config.clone(), source_name.clone(), def.body); let lo = p.span.lo; diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 7637b769f93..a618c98ff77 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -23,8 +23,7 @@ use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; use rustc::dep_graph::DepNode; use rustc::hir::map as hir_map; use rustc::hir::map::DefKey; -use rustc::mir::repr::Mir; -use rustc::mir::mir_map::MirMap; +use rustc::mir::Mir; use rustc::util::nodemap::{NodeSet, DefIdMap}; use rustc_back::PanicStrategy; @@ -207,11 +206,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.get_crate_data(impl_did.krate).is_default_impl(impl_did.index) } - fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool { - self.dep_graph.read(DepNode::MetaData(did)); - self.get_crate_data(did.krate).is_extern_item(did.index, tcx) - } - fn is_foreign_item(&self, did: DefId) -> bool { self.get_crate_data(did.krate).is_foreign_item(did.index) } @@ -467,10 +461,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.defid_for_inlined_node.borrow().get(&node_id).map(|x| *x) } - fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Option<Mir<'tcx>> { + fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx> { self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).maybe_get_item_mir(tcx, def.index) + self.get_crate_data(def.krate).maybe_get_item_mir(tcx, def.index).unwrap_or_else(|| { + bug!("get_item_mir: missing MIR for {}", tcx.item_path_str(def)) + }) } fn is_item_mir_available(&self, def: DefId) -> bool { @@ -523,10 +518,9 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, reexports: &def::ExportMap, link_meta: &LinkMeta, - reachable: &NodeSet, - mir_map: &MirMap<'tcx>) -> Vec<u8> + reachable: &NodeSet) -> Vec<u8> { - encoder::encode_metadata(tcx, self, reexports, link_meta, reachable, mir_map) + encoder::encode_metadata(tcx, self, reexports, link_meta, reachable) } fn metadata_encoding_version(&self) -> &[u8] diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 0d42ff8ce27..ccd497860de 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -30,7 +30,7 @@ use rustc::ty::subst::Substs; use rustc_const_math::ConstInt; -use rustc::mir::repr::Mir; +use rustc::mir::Mir; use std::borrow::Cow; use std::cell::Ref; @@ -1009,30 +1009,6 @@ impl<'a, 'tcx> CrateMetadata { constness == hir::Constness::Const } - pub fn is_extern_item(&self, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool { - let item = match self.maybe_entry(id) { - Some(item) => item.decode(self), - None => return false, - }; - let applicable = match item.kind { - EntryKind::ImmStatic | - EntryKind::MutStatic | - EntryKind::ForeignImmStatic | - EntryKind::ForeignMutStatic => true, - - EntryKind::Fn(_) | - EntryKind::ForeignFn(_) => self.get_generics(id, tcx).types.is_empty(), - - _ => false, - }; - - if applicable { - attr::contains_extern_indicator(tcx.sess.diagnostic(), &self.get_attributes(&item)) - } else { - false - } - } - pub fn is_foreign_item(&self, id: DefIndex) -> bool { match self.entry(id).kind { EntryKind::ForeignImmStatic | @@ -1138,6 +1114,14 @@ impl<'a, 'tcx> CrateMetadata { match reusable_filemap { Some(fm) => { + + debug!("CrateMetaData::imported_filemaps reuse \ + filemap {:?} original (start_pos {:?} end_pos {:?}) \ + translated (start_pos {:?} end_pos {:?})", + filemap_to_import.name, + filemap_to_import.start_pos, filemap_to_import.end_pos, + fm.start_pos, fm.end_pos); + cstore::ImportedFileMap { original_start_pos: filemap_to_import.start_pos, original_end_pos: filemap_to_import.end_pos, @@ -1176,6 +1160,12 @@ impl<'a, 'tcx> CrateMetadata { source_length, lines, multibyte_chars); + debug!("CrateMetaData::imported_filemaps alloc \ + filemap {:?} original (start_pos {:?} end_pos {:?}) \ + translated (start_pos {:?} end_pos {:?})", + local_version.name, start_pos, end_pos, + local_version.start_pos, local_version.end_pos); + cstore::ImportedFileMap { original_start_pos: start_pos, original_end_pos: end_pos, @@ -1193,6 +1183,10 @@ impl<'a, 'tcx> CrateMetadata { } fn are_equal_modulo_startpos(fm1: &syntax_pos::FileMap, fm2: &syntax_pos::FileMap) -> bool { + if fm1.byte_length() != fm2.byte_length() { + return false; + } + if fm1.name != fm2.name { return false; } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 21630dde5f5..e8734e42757 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -22,7 +22,6 @@ use rustc::mir; use rustc::traits::specialization_graph; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::mir::mir_map::MirMap; use rustc::session::config::{self, CrateTypeProcMacro}; use rustc::util::nodemap::{FnvHashMap, NodeSet}; @@ -51,7 +50,6 @@ pub struct EncodeContext<'a, 'tcx: 'a> { link_meta: &'a LinkMeta, cstore: &'a cstore::CStore, reachable: &'a NodeSet, - mir_map: &'a MirMap<'tcx>, lazy_state: LazyState, type_shorthands: FnvHashMap<Ty<'tcx>, usize>, @@ -117,7 +115,8 @@ impl<'a, 'tcx> SpecializedEncoder<Ty<'tcx>> for EncodeContext<'a, 'tcx> { } impl<'a, 'tcx> SpecializedEncoder<ty::GenericPredicates<'tcx>> for EncodeContext<'a, 'tcx> { - fn specialized_encode(&mut self, predicates: &ty::GenericPredicates<'tcx>) + fn specialized_encode(&mut self, + predicates: &ty::GenericPredicates<'tcx>) -> Result<(), Self::Error> { predicates.parent.encode(self)?; predicates.predicates.len().encode(self)?; @@ -142,13 +141,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { r } - fn emit_lazy_distance(&mut self, position: usize, min_size: usize) + fn emit_lazy_distance(&mut self, + position: usize, + min_size: usize) -> Result<(), <Self as Encoder>::Error> { let min_end = position + min_size; let distance = match self.lazy_state { - LazyState::NoNode => { - bug!("emit_lazy_distance: outside of a metadata node") - } + LazyState::NoNode => bug!("emit_lazy_distance: outside of a metadata node"), LazyState::NodeStart(start) => { assert!(min_end <= start); start - min_end @@ -172,7 +171,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } fn lazy_seq<I, T>(&mut self, iter: I) -> LazySeq<T> - where I: IntoIterator<Item=T>, T: Encodable { + where I: IntoIterator<Item = T>, + T: Encodable + { self.emit_node(|ecx, pos| { let len = iter.into_iter().map(|value| value.encode(ecx).unwrap()).count(); @@ -182,7 +183,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } fn lazy_seq_ref<'b, I, T>(&mut self, iter: I) -> LazySeq<T> - where I: IntoIterator<Item=&'b T>, T: 'b + Encodable { + where I: IntoIterator<Item = &'b T>, + T: 'b + Encodable + { self.emit_node(|ecx, pos| { let len = iter.into_iter().map(|value| value.encode(ecx).unwrap()).count(); @@ -192,11 +195,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } /// Encode the given value or a previously cached shorthand. - fn encode_with_shorthand<T, U, M>(&mut self, value: &T, variant: &U, map: M) + fn encode_with_shorthand<T, U, M>(&mut self, + value: &T, + variant: &U, + map: M) -> Result<(), <Self as Encoder>::Error> - where M: for<'b> Fn(&'b mut Self) -> &'b mut FnvHashMap<T, usize>, - T: Clone + Eq + Hash, - U: Encodable { + where M: for<'b> Fn(&'b mut Self) -> &'b mut FnvHashMap<T, usize>, + T: Clone + Eq + Hash, + U: Encodable + { let existing_shorthand = map(self).get(value).cloned(); if let Some(shorthand) = existing_shorthand { return self.emit_usize(shorthand); @@ -208,9 +215,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // The shorthand encoding uses the same usize as the // discriminant, with an offset so they can't conflict. - let discriminant = unsafe { - intrinsics::discriminant_value(variant) - }; + let discriminant = unsafe { intrinsics::discriminant_value(variant) }; assert!(discriminant < SHORTHAND_OFFSET as u64); let shorthand = start + SHORTHAND_OFFSET; @@ -250,8 +255,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { /// the right to access any information in the adt-def (including, /// e.g., the length of the various vectors). fn encode_enum_variant_info(&mut self, - (enum_did, Untracked(index)): - (DefId, Untracked<usize>)) -> Entry<'tcx> { + (enum_did, Untracked(index)): (DefId, Untracked<usize>)) + -> Entry<'tcx> { let tcx = self.tcx; let def = tcx.lookup_adt_def(enum_did); let variant = &def.variants[index]; @@ -260,7 +265,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let data = VariantData { ctor_kind: variant.ctor_kind, disr: variant.disr_val.to_u64_unchecked(), - struct_ctor: None + struct_ctor: None, }; let enum_id = tcx.map.as_local_node_id(enum_did).unwrap(); @@ -285,24 +290,23 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { predicates: Some(self.encode_predicates(def_id)), ast: None, - mir: None + mir: None, } } fn encode_info_for_mod(&mut self, - FromId(id, (md, attrs, vis)): - FromId<(&hir::Mod, &[ast::Attribute], &hir::Visibility)>) + FromId(id, (md, attrs, vis)): FromId<(&hir::Mod, + &[ast::Attribute], + &hir::Visibility)>) -> Entry<'tcx> { let tcx = self.tcx; let def_id = tcx.map.local_def_id(id); let data = ModData { reexports: match self.reexports.get(&id) { - Some(exports) if *vis == hir::Public => { - self.lazy_seq_ref(exports) - } - _ => LazySeq::empty() - } + Some(exports) if *vis == hir::Public => self.lazy_seq_ref(exports), + _ => LazySeq::empty(), + }, }; Entry { @@ -353,8 +357,7 @@ impl Visibility for ty::Visibility { } impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { - fn encode_fields(&mut self, - adt_def_id: DefId) { + fn encode_fields(&mut self, adt_def_id: DefId) { let def = self.tcx.lookup_adt_def(adt_def_id); for (variant_index, variant) in def.variants.iter().enumerate() { for (field_index, field) in variant.fields.iter().enumerate() { @@ -374,8 +377,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { /// the adt-def (including, e.g., the length of the various /// vectors). fn encode_field(&mut self, - (adt_def_id, Untracked((variant_index, field_index))): - (DefId, Untracked<(usize, usize)>)) -> Entry<'tcx> { + (adt_def_id, Untracked((variant_index, field_index))): (DefId, + Untracked<(usize, + usize)>)) + -> Entry<'tcx> { let tcx = self.tcx; let variant = &tcx.lookup_adt_def(adt_def_id).variants[variant_index]; let field = &variant.fields[field_index]; @@ -400,19 +405,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { predicates: Some(self.encode_predicates(def_id)), ast: None, - mir: None + mir: None, } } - fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) - -> Entry<'tcx> { + fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<'tcx> { let tcx = self.tcx; let variant = tcx.lookup_adt_def(adt_def_id).struct_variant(); let data = VariantData { ctor_kind: variant.ctor_kind, disr: variant.disr_val.to_u64_unchecked(), - struct_ctor: Some(def_id.index) + struct_ctor: Some(def_id.index), }; let struct_id = tcx.map.as_local_node_id(adt_def_id).unwrap(); @@ -434,7 +438,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { predicates: Some(self.encode_predicates(def_id)), ast: None, - mir: None + mir: None, } } @@ -469,7 +473,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let fn_data = if let hir::MethodTraitItem(ref sig, _) = ast_item.node { FnData { constness: hir::Constness::NotConst, - arg_names: self.encode_fn_arg_names(&sig.decl) + arg_names: self.encode_fn_arg_names(&sig.decl), } } else { bug!() @@ -477,13 +481,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let data = MethodData { fn_data: fn_data, container: container(method_ty.has_body), - explicit_self: self.lazy(&method_ty.explicit_self) + explicit_self: self.lazy(&method_ty.explicit_self), }; EntryKind::Method(self.lazy(&data)) } - ty::TypeTraitItem(_) => { - EntryKind::AssociatedType(container(false)) - } + ty::TypeTraitItem(_) => EntryKind::AssociatedType(container(false)), }; Entry { @@ -497,9 +499,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { ty: match trait_item { ty::ConstTraitItem(_) | - ty::MethodTraitItem(_) => { - Some(self.encode_item_type(def_id)) - } + ty::MethodTraitItem(_) => Some(self.encode_item_type(def_id)), ty::TypeTraitItem(ref associated_type) => { associated_type.ty.map(|ty| self.lazy(&ty)) } @@ -515,7 +515,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } else { None }, - mir: self.encode_mir(def_id) + mir: self.encode_mir(def_id), } } @@ -527,18 +527,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let container = match ast_item.defaultness { hir::Defaultness::Default => AssociatedContainer::ImplDefault, - hir::Defaultness::Final => AssociatedContainer::ImplFinal + hir::Defaultness::Final => AssociatedContainer::ImplFinal, }; let kind = match impl_item { - ty::ConstTraitItem(_) => { - EntryKind::AssociatedConst(container) - } + ty::ConstTraitItem(_) => EntryKind::AssociatedConst(container), ty::MethodTraitItem(ref method_ty) => { let fn_data = if let hir::ImplItemKind::Method(ref sig, _) = ast_item.node { FnData { constness: sig.constness, - arg_names: self.encode_fn_arg_names(&sig.decl) + arg_names: self.encode_fn_arg_names(&sig.decl), } } else { bug!() @@ -546,13 +544,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let data = MethodData { fn_data: fn_data, container: container, - explicit_self: self.lazy(&method_ty.explicit_self) + explicit_self: self.lazy(&method_ty.explicit_self), }; EntryKind::Method(self.lazy(&data)) } - ty::TypeTraitItem(_) => { - EntryKind::AssociatedType(container) - } + ty::TypeTraitItem(_) => EntryKind::AssociatedType(container), }; let (ast, mir) = if let ty::ConstTraitItem(_) = impl_item { @@ -578,9 +574,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { ty: match impl_item { ty::ConstTraitItem(_) | - ty::MethodTraitItem(_) => { - Some(self.encode_item_type(def_id)) - } + ty::MethodTraitItem(_) => Some(self.encode_item_type(def_id)), ty::TypeTraitItem(ref associated_type) => { associated_type.ty.map(|ty| self.lazy(&ty)) } @@ -595,11 +589,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } else { None }, - mir: if mir { - self.encode_mir(def_id) - } else { - None - } + mir: if mir { self.encode_mir(def_id) } else { None }, } } @@ -613,8 +603,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { })) } - fn encode_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::repr::Mir<'tcx>>> { - self.mir_map.map.get(&def_id).map(|mir| self.lazy(mir)) + fn encode_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::Mir<'tcx>>> { + self.tcx.mir_map.borrow().get(&def_id).map(|mir| self.lazy(&*mir.borrow())) } // Encodes the inherent implementations of a structure, enumeration, or trait. @@ -638,8 +628,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tcx.lookup_deprecation(def_id).map(|depr| self.lazy(&depr)) } - fn encode_info_for_item(&mut self, - (def_id, item): (DefId, &hir::Item)) -> Entry<'tcx> { + fn encode_info_for_item(&mut self, (def_id, item): (DefId, &hir::Item)) -> Entry<'tcx> { let tcx = self.tcx; debug!("encoding info for item at {}", @@ -652,7 +641,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ItemFn(ref decl, _, constness, ..) => { let data = FnData { constness: constness, - arg_names: self.encode_fn_arg_names(&decl) + arg_names: self.encode_fn_arg_names(&decl), }; EntryKind::Fn(self.lazy(&data)) @@ -666,9 +655,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ItemStruct(ref struct_def, _) => { let variant = tcx.lookup_adt_def(def_id).struct_variant(); - /* Encode def_ids for each field and method - for methods, write all the stuff get_trait_method - needs to know*/ + // Encode def_ids for each field and method + // for methods, write all the stuff get_trait_method + // needs to know let struct_ctor = if !struct_def.is_struct() { Some(tcx.map.local_def_id(struct_def.id()).index) } else { @@ -677,7 +666,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { EntryKind::Struct(self.lazy(&VariantData { ctor_kind: variant.ctor_kind, disr: variant.disr_val.to_u64_unchecked(), - struct_ctor: struct_ctor + struct_ctor: struct_ctor, })) } hir::ItemUnion(..) => { @@ -686,7 +675,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { EntryKind::Union(self.lazy(&VariantData { ctor_kind: variant.ctor_kind, disr: variant.disr_val.to_u64_unchecked(), - struct_ctor: None + struct_ctor: None, })) } hir::ItemDefaultImpl(..) => { @@ -694,7 +683,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { polarity: hir::ImplPolarity::Positive, parent_impl: None, coerce_unsized_kind: None, - trait_ref: tcx.impl_trait_ref(def_id).map(|trait_ref| self.lazy(&trait_ref)) + trait_ref: tcx.impl_trait_ref(def_id).map(|trait_ref| self.lazy(&trait_ref)), }; EntryKind::DefaultImpl(self.lazy(&data)) @@ -716,9 +705,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let data = ImplData { polarity: polarity, parent_impl: parent, - coerce_unsized_kind: tcx.custom_coerce_unsized_kinds.borrow() - .get(&def_id).cloned(), - trait_ref: trait_ref.map(|trait_ref| self.lazy(&trait_ref)) + coerce_unsized_kind: tcx.custom_coerce_unsized_kinds + .borrow() + .get(&def_id) + .cloned(), + trait_ref: trait_ref.map(|trait_ref| self.lazy(&trait_ref)), }; EntryKind::Impl(self.lazy(&data)) @@ -730,14 +721,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { paren_sugar: trait_def.paren_sugar, has_default_impl: tcx.trait_has_default_impl(def_id), trait_ref: self.lazy(&trait_def.trait_ref), - super_predicates: self.lazy(&tcx.lookup_super_predicates(def_id)) + super_predicates: self.lazy(&tcx.lookup_super_predicates(def_id)), }; EntryKind::Trait(self.lazy(&data)) } - hir::ItemExternCrate(_) | hir::ItemUse(_) => { - bug!("cannot encode info for item {:?}", item) - } + hir::ItemExternCrate(_) | + hir::ItemUse(_) => bug!("cannot encode info for item {:?}", item), }; Entry { @@ -747,9 +737,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { attributes: self.encode_attributes(&item.attrs), children: match item.node { hir::ItemForeignMod(ref fm) => { - self.lazy_seq(fm.items.iter().map(|foreign_item| { - tcx.map.local_def_id(foreign_item.id).index - })) + self.lazy_seq(fm.items + .iter() + .map(|foreign_item| tcx.map.local_def_id(foreign_item.id).index)) } hir::ItemEnum(..) => { let def = self.tcx.lookup_adt_def(def_id); @@ -773,7 +763,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { def_id.index })) } - _ => LazySeq::empty() + _ => LazySeq::empty(), }, stability: self.encode_stability(def_id), deprecation: self.encode_deprecation(def_id), @@ -786,20 +776,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ItemEnum(..) | hir::ItemStruct(..) | hir::ItemUnion(..) | - hir::ItemImpl(..) => { - Some(self.encode_item_type(def_id)) - } - _ => None + hir::ItemImpl(..) => Some(self.encode_item_type(def_id)), + _ => None, }, inherent_impls: self.encode_inherent_implementations(def_id), variances: match item.node { hir::ItemEnum(..) | hir::ItemStruct(..) | hir::ItemUnion(..) | - hir::ItemTrait(..) => { - self.encode_item_variances(def_id) - } - _ => LazySeq::empty() + hir::ItemTrait(..) => self.encode_item_variances(def_id), + _ => LazySeq::empty(), }, generics: match item.node { hir::ItemStatic(..) | @@ -810,10 +796,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ItemStruct(..) | hir::ItemUnion(..) | hir::ItemImpl(..) | - hir::ItemTrait(..) => { - Some(self.encode_generics(def_id)) - } - _ => None + hir::ItemTrait(..) => Some(self.encode_generics(def_id)), + _ => None, }, predicates: match item.node { hir::ItemStatic(..) | @@ -824,10 +808,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ItemStruct(..) | hir::ItemUnion(..) | hir::ItemImpl(..) | - hir::ItemTrait(..) => { - Some(self.encode_predicates(def_id)) - } - _ => None + hir::ItemTrait(..) => Some(self.encode_predicates(def_id)), + _ => None, }, ast: match item.node { @@ -835,12 +817,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ItemFn(_, _, hir::Constness::Const, ..) => { Some(self.encode_inlined_item(InlinedItemRef::Item(def_id, item))) } - _ => None + _ => None, }, mir: match item.node { - hir::ItemConst(..) => { - self.encode_mir(def_id) - } + hir::ItemConst(..) => self.encode_mir(def_id), hir::ItemFn(_, _, constness, _, ref generics, _) => { let tps_len = generics.ty_params.len(); let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs); @@ -850,8 +830,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { None } } - _ => None - } + _ => None, + }, } } } @@ -861,8 +841,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { /// encode some sub-items. Usually we want some info from the item /// so it's easier to do that here then to wait until we would encounter /// normally in the visitor walk. - fn encode_addl_info_for_item(&mut self, - item: &hir::Item) { + fn encode_addl_info_for_item(&mut self, item: &hir::Item) { let def_id = self.tcx.map.local_def_id(item.id); match item.node { hir::ItemStatic(..) | @@ -930,12 +909,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ForeignItemFn(ref fndecl, _) => { let data = FnData { constness: hir::Constness::NotConst, - arg_names: self.encode_fn_arg_names(&fndecl) + arg_names: self.encode_fn_arg_names(&fndecl), }; EntryKind::ForeignFn(self.lazy(&data)) } hir::ForeignItemStatic(_, true) => EntryKind::ForeignMutStatic, - hir::ForeignItemStatic(_, false) => EntryKind::ForeignImmStatic + hir::ForeignItemStatic(_, false) => EntryKind::ForeignImmStatic, }; Entry { @@ -954,7 +933,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { predicates: Some(self.encode_predicates(def_id)), ast: None, - mir: None + mir: None, } } } @@ -972,10 +951,9 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> { intravisit::walk_item(self, item); let def_id = self.index.tcx.map.local_def_id(item.id); match item.node { - hir::ItemExternCrate(_) | hir::ItemUse(_) => (), // ignore these - _ => self.index.record(def_id, - EncodeContext::encode_info_for_item, - (def_id, item)), + hir::ItemExternCrate(_) | + hir::ItemUse(_) => (), // ignore these + _ => self.index.record(def_id, EncodeContext::encode_info_for_item, (def_id, item)), } self.index.encode_addl_info_for_item(item); } @@ -996,9 +974,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { fn encode_info_for_ty(&mut self, ty: &hir::Ty) { if let hir::TyImplTrait(_) = ty.node { let def_id = self.tcx.map.local_def_id(ty.id); - self.record(def_id, - EncodeContext::encode_info_for_anon_ty, - def_id); + self.record(def_id, EncodeContext::encode_info_for_anon_ty, def_id); } } @@ -1006,11 +982,9 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { match expr.node { hir::ExprClosure(..) => { let def_id = self.tcx.map.local_def_id(expr.id); - self.record(def_id, - EncodeContext::encode_info_for_closure, - def_id); + self.record(def_id, EncodeContext::encode_info_for_closure, def_id); } - _ => { } + _ => {} } } } @@ -1033,7 +1007,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { predicates: Some(self.encode_predicates(def_id)), ast: None, - mir: None + mir: None, } } @@ -1042,7 +1016,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let data = ClosureData { kind: tcx.closure_kind(def_id), - ty: self.lazy(&tcx.tables.borrow().closure_tys[&def_id]) + ty: self.lazy(&tcx.tables.borrow().closure_tys[&def_id]), }; Entry { @@ -1061,7 +1035,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { predicates: None, ast: None, - mir: self.encode_mir(def_id) + mir: self.encode_mir(def_id), } } @@ -1071,9 +1045,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { index.record(DefId::local(CRATE_DEF_INDEX), EncodeContext::encode_info_for_mod, FromId(CRATE_NODE_ID, (&krate.module, &krate.attrs, &hir::Public))); - let mut visitor = EncodeVisitor { - index: index, - }; + let mut visitor = EncodeVisitor { index: index }; krate.visit_all_items(&mut visitor); visitor.index.into_items() } @@ -1083,8 +1055,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } fn encode_crate_deps(&mut self) -> LazySeq<CrateDep> { - fn get_ordered_deps(cstore: &cstore::CStore) - -> Vec<(CrateNum, Rc<cstore::CrateMetadata>)> { + fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<(CrateNum, Rc<cstore::CrateMetadata>)> { // Pull the cnums and name,vers,hash out of cstore let mut deps = Vec::new(); cstore.iter_crate_data(|cnum, val| { @@ -1113,13 +1084,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { CrateDep { name: syntax::parse::token::intern(dep.name()), hash: dep.hash(), - explicitly_linked: dep.explicitly_linked.get() + explicitly_linked: dep.explicitly_linked.get(), } })) } - fn encode_lang_items(&mut self) - -> (LazySeq<(DefIndex, usize)>, LazySeq<lang_items::LangItem>) { + fn encode_lang_items(&mut self) -> (LazySeq<(DefIndex, usize)>, LazySeq<lang_items::LangItem>) { let tcx = self.tcx; let lang_items = tcx.lang_items.items().iter(); (self.lazy_seq(lang_items.enumerate().filter_map(|(i, &opt_def_id)| { @@ -1129,7 +1099,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } None - })), self.lazy_seq_ref(&tcx.lang_items.missing)) + })), + self.lazy_seq_ref(&tcx.lang_items.missing)) } fn encode_native_libraries(&mut self) -> LazySeq<(NativeLibraryKind, String)> { @@ -1137,9 +1108,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.lazy_seq(used_libraries.into_iter().filter_map(|(lib, kind)| { match kind { cstore::NativeStatic => None, // these libraries are not propagated - cstore::NativeFramework | cstore::NativeUnknown => { - Some((kind, lib)) - } + cstore::NativeFramework | cstore::NativeUnknown => Some((kind, lib)), } })) } @@ -1147,13 +1116,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_codemap(&mut self) -> LazySeq<syntax_pos::FileMap> { let codemap = self.tcx.sess.codemap(); let all_filemaps = codemap.files.borrow(); - self.lazy_seq_ref(all_filemaps.iter().filter(|filemap| { - // No need to export empty filemaps, as they can't contain spans - // that need translation. - // Also no need to re-export imported filemaps, as any downstream - // crate will import them from their original source. - !filemap.lines.borrow().is_empty() && !filemap.is_imported() - }).map(|filemap| &**filemap)) + self.lazy_seq_ref(all_filemaps.iter() + .filter(|filemap| { + // No need to export empty filemaps, as they can't contain spans + // that need translation. + // Also no need to re-export imported filemaps, as any downstream + // crate will import them from their original source. + !filemap.lines.borrow().is_empty() && !filemap.is_imported() + }) + .map(|filemap| &**filemap)) } /// Serialize the text of the exported macros @@ -1164,15 +1135,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { name: def.name, attrs: def.attrs.to_vec(), span: def.span, - body: ::syntax::print::pprust::tts_to_string(&def.body) + body: ::syntax::print::pprust::tts_to_string(&def.body), } })) } } -struct ImplVisitor<'a, 'tcx:'a> { +struct ImplVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - impls: FnvHashMap<DefId, Vec<DefIndex>> + impls: FnvHashMap<DefId, Vec<DefIndex>>, } impl<'a, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'tcx> { @@ -1180,7 +1151,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'tcx> { if let hir::ItemImpl(..) = item.node { let impl_id = self.tcx.map.local_def_id(item.id); if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) { - self.impls.entry(trait_ref.def_id) + self.impls + .entry(trait_ref.def_id) .or_insert(vec![]) .push(impl_id.index); } @@ -1193,16 +1165,19 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_impls(&mut self) -> LazySeq<TraitImpls> { let mut visitor = ImplVisitor { tcx: self.tcx, - impls: FnvHashMap() + impls: FnvHashMap(), }; self.tcx.map.krate().visit_all_items(&mut visitor); - let all_impls: Vec<_> = visitor.impls.into_iter().map(|(trait_def_id, impls)| { - TraitImpls { - trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index), - impls: self.lazy_seq(impls) - } - }).collect(); + let all_impls: Vec<_> = visitor.impls + .into_iter() + .map(|(trait_def_id, impls)| { + TraitImpls { + trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index), + impls: self.lazy_seq(impls), + } + }) + .collect(); self.lazy_seq(all_impls) } @@ -1232,7 +1207,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } })) } - None => LazySeq::empty() + None => LazySeq::empty(), } } @@ -1291,9 +1266,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hash: link_meta.crate_hash, disambiguator: tcx.sess.local_crate_disambiguator().to_string(), panic_strategy: tcx.sess.panic_strategy(), - plugin_registrar_fn: tcx.sess.plugin_registrar_fn.get().map(|id| { - tcx.map.local_def_id(id).index - }), + plugin_registrar_fn: tcx.sess + .plugin_registrar_fn + .get() + .map(|id| tcx.map.local_def_id(id).index), macro_derive_registrar: if is_proc_macro { let id = tcx.sess.derive_registrar_fn.get().unwrap(); Some(tcx.map.local_def_id(id).index) @@ -1368,8 +1344,8 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cstore: &cstore::CStore, reexports: &def::ExportMap, link_meta: &LinkMeta, - reachable: &NodeSet, - mir_map: &MirMap<'tcx>) -> Vec<u8> { + reachable: &NodeSet) + -> Vec<u8> { let mut cursor = Cursor::new(vec![]); cursor.write_all(METADATA_HEADER).unwrap(); @@ -1377,17 +1353,17 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cursor.write_all(&[0, 0, 0, 0]).unwrap(); let root = EncodeContext { - opaque: opaque::Encoder::new(&mut cursor), - tcx: tcx, - reexports: reexports, - link_meta: link_meta, - cstore: cstore, - reachable: reachable, - mir_map: mir_map, - lazy_state: LazyState::NoNode, - type_shorthands: Default::default(), - predicate_shorthands: Default::default() - }.encode_crate_root(); + opaque: opaque::Encoder::new(&mut cursor), + tcx: tcx, + reexports: reexports, + link_meta: link_meta, + cstore: cstore, + reachable: reachable, + lazy_state: LazyState::NoNode, + type_shorthands: Default::default(), + predicate_shorthands: Default::default(), + } + .encode_crate_root(); let mut result = cursor.into_inner(); // Encode the root position. @@ -1395,8 +1371,8 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let pos = root.position; result[header + 0] = (pos >> 24) as u8; result[header + 1] = (pos >> 16) as u8; - result[header + 2] = (pos >> 8) as u8; - result[header + 3] = (pos >> 0) as u8; + result[header + 2] = (pos >> 8) as u8; + result[header + 3] = (pos >> 0) as u8; result } diff --git a/src/librustc_metadata/index.rs b/src/librustc_metadata/index.rs index ef83251f51e..53e6988c756 100644 --- a/src/librustc_metadata/index.rs +++ b/src/librustc_metadata/index.rs @@ -28,9 +28,7 @@ pub struct Index { impl Index { pub fn new(max_index: usize) -> Index { - Index { - positions: vec![u32::MAX; max_index] - } + Index { positions: vec![u32::MAX; max_index] } } pub fn record(&mut self, def_id: DefId, entry: Lazy<Entry>) { @@ -46,7 +44,9 @@ impl Index { assert!(self.positions[item] == u32::MAX, "recorded position for item {:?} twice, first at {:?} and now at {:?}", - item, self.positions[item], position); + item, + self.positions[item], + position); self.positions[item] = position.to_le(); } @@ -67,7 +67,8 @@ impl<'tcx> LazySeq<Index> { let index = def_index.as_usize(); debug!("Index::lookup: index={:?} words.len={:?}", - index, words.len()); + index, + words.len()); let position = u32::from_le(words[index]); if position == u32::MAX { @@ -79,8 +80,9 @@ impl<'tcx> LazySeq<Index> { } } - pub fn iter_enumerated<'a>(&self, bytes: &'a [u8]) - -> impl Iterator<Item=(DefIndex, Lazy<Entry<'tcx>>)> + 'a { + pub fn iter_enumerated<'a>(&self, + bytes: &'a [u8]) + -> impl Iterator<Item = (DefIndex, Lazy<Entry<'tcx>>)> + 'a { let words = &bytes_to_words(&bytes[self.position..])[..self.len]; words.iter().enumerate().filter_map(|(index, &position)| { if position == u32::MAX { diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index aeb6f63252c..9938e20d186 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -138,11 +138,11 @@ pub trait DepGraphRead { } impl DepGraphRead for DefId { - fn read(&self, _tcx: TyCtxt) { } + fn read(&self, _tcx: TyCtxt) {} } impl DepGraphRead for ast::NodeId { - fn read(&self, _tcx: TyCtxt) { } + fn read(&self, _tcx: TyCtxt) {} } impl<T> DepGraphRead for Option<T> @@ -179,8 +179,8 @@ macro_rules! read_tuple { } } } -read_tuple!(A,B); -read_tuple!(A,B,C); +read_tuple!(A, B); +read_tuple!(A, B, C); macro_rules! read_hir { ($t:ty) => { @@ -208,7 +208,7 @@ read_hir!(hir::ForeignItem); pub struct Untracked<T>(pub T); impl<T> DepGraphRead for Untracked<T> { - fn read(&self, _tcx: TyCtxt) { } + fn read(&self, _tcx: TyCtxt) {} } /// Newtype that can be used to package up misc data extracted from a diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 300c5f0dec7..ef81dbd7f29 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -30,8 +30,10 @@ #![feature(specialization)] #![feature(staged_api)] -#[macro_use] extern crate log; -#[macro_use] extern crate syntax; +#[macro_use] +extern crate log; +#[macro_use] +extern crate syntax; extern crate syntax_pos; extern crate flate; extern crate serialize as rustc_serialize; // used by deriving diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index e684cd16366..0461d7ec061 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -273,7 +273,7 @@ pub struct ArchiveMetadata { pub struct CratePaths { pub ident: String, pub dylib: Option<PathBuf>, - pub rlib: Option<PathBuf> + pub rlib: Option<PathBuf>, } pub const METADATA_FILENAME: &'static str = "rust.metadata.bin"; @@ -281,14 +281,14 @@ pub const METADATA_FILENAME: &'static str = "rust.metadata.bin"; #[derive(Copy, Clone, PartialEq)] enum CrateFlavor { Rlib, - Dylib + Dylib, } impl fmt::Display for CrateFlavor { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(match *self { CrateFlavor::Rlib => "rlib", - CrateFlavor::Dylib => "dylib" + CrateFlavor::Dylib => "dylib", }) } } @@ -296,10 +296,10 @@ impl fmt::Display for CrateFlavor { impl CratePaths { fn paths(&self) -> Vec<PathBuf> { match (&self.dylib, &self.rlib) { - (&None, &None) => vec!(), + (&None, &None) => vec![], (&Some(ref p), &None) | - (&None, &Some(ref p)) => vec!(p.clone()), - (&Some(ref p1), &Some(ref p2)) => vec!(p1.clone(), p2.clone()), + (&None, &Some(ref p)) => vec![p.clone()], + (&Some(ref p1), &Some(ref p2)) => vec![p1.clone(), p2.clone()], } } } @@ -316,53 +316,72 @@ impl<'a> Context<'a> { pub fn report_errs(&mut self) -> ! { let add = match self.root { &None => String::new(), - &Some(ref r) => format!(" which `{}` depends on", - r.ident) + &Some(ref r) => format!(" which `{}` depends on", r.ident), }; let mut err = if !self.rejected_via_hash.is_empty() { - struct_span_err!(self.sess, self.span, E0460, + struct_span_err!(self.sess, + self.span, + E0460, "found possibly newer version of crate `{}`{}", - self.ident, add) + self.ident, + add) } else if !self.rejected_via_triple.is_empty() { - struct_span_err!(self.sess, self.span, E0461, + struct_span_err!(self.sess, + self.span, + E0461, "couldn't find crate `{}` with expected target triple {}{}", - self.ident, self.triple, add) + self.ident, + self.triple, + add) } else if !self.rejected_via_kind.is_empty() { - struct_span_err!(self.sess, self.span, E0462, + struct_span_err!(self.sess, + self.span, + E0462, "found staticlib `{}` instead of rlib or dylib{}", - self.ident, add) + self.ident, + add) } else if !self.rejected_via_version.is_empty() { - struct_span_err!(self.sess, self.span, E0514, + struct_span_err!(self.sess, + self.span, + E0514, "found crate `{}` compiled by an incompatible version of rustc{}", - self.ident, add) + self.ident, + add) } else { - let mut err = struct_span_err!(self.sess, self.span, E0463, + let mut err = struct_span_err!(self.sess, + self.span, + E0463, "can't find crate for `{}`{}", - self.ident, add); + self.ident, + add); err.span_label(self.span, &format!("can't find crate")); err }; if !self.rejected_via_triple.is_empty() { let mismatches = self.rejected_via_triple.iter(); - for (i, &CrateMismatch{ ref path, ref got }) in mismatches.enumerate() { + for (i, &CrateMismatch { ref path, ref got }) in mismatches.enumerate() { err.note(&format!("crate `{}`, path #{}, triple {}: {}", - self.ident, i+1, got, path.display())); + self.ident, + i + 1, + got, + path.display())); } } if !self.rejected_via_hash.is_empty() { err.note("perhaps that crate needs to be recompiled?"); let mismatches = self.rejected_via_hash.iter(); - for (i, &CrateMismatch{ ref path, .. }) in mismatches.enumerate() { - err.note(&format!("crate `{}` path #{}: {}", - self.ident, i+1, path.display())); + for (i, &CrateMismatch { ref path, .. }) in mismatches.enumerate() { + err.note(&format!("crate `{}` path #{}: {}", self.ident, i + 1, path.display())); } match self.root { &None => {} &Some(ref r) => { for (i, path) in r.paths().iter().enumerate() { err.note(&format!("crate `{}` path #{}: {}", - r.ident, i+1, path.display())); + r.ident, + i + 1, + path.display())); } } } @@ -371,8 +390,7 @@ impl<'a> Context<'a> { err.help("please recompile that crate using --crate-type lib"); let mismatches = self.rejected_via_kind.iter(); for (i, &CrateMismatch { ref path, .. }) in mismatches.enumerate() { - err.note(&format!("crate `{}` path #{}: {}", - self.ident, i+1, path.display())); + err.note(&format!("crate `{}` path #{}: {}", self.ident, i + 1, path.display())); } } if !self.rejected_via_version.is_empty() { @@ -381,7 +399,10 @@ impl<'a> Context<'a> { let mismatches = self.rejected_via_version.iter(); for (i, &CrateMismatch { ref path, ref got }) in mismatches.enumerate() { err.note(&format!("crate `{}` path #{}: {} compiled by {:?}", - self.ident, i+1, path.display(), got)); + self.ident, + i + 1, + path.display(), + got)); } } @@ -410,7 +431,7 @@ impl<'a> Context<'a> { let staticlib_prefix = format!("{}{}", staticpair.0, self.crate_name); let mut candidates = FnvHashMap(); - let mut staticlibs = vec!(); + let mut staticlibs = vec![]; // First, find all possible candidate rlibs and dylibs purely based on // the name of the files themselves. We're trying to match against an @@ -430,38 +451,36 @@ impl<'a> Context<'a> { None => return FileDoesntMatch, Some(file) => file, }; - let (hash, rlib) = if file.starts_with(&rlib_prefix[..]) && - file.ends_with(".rlib") { - (&file[(rlib_prefix.len()) .. (file.len() - ".rlib".len())], - true) + let (hash, rlib) = if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") { + (&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], true) } else if file.starts_with(&dylib_prefix) && - file.ends_with(&dypair.1) { - (&file[(dylib_prefix.len()) .. (file.len() - dypair.1.len())], - false) + file.ends_with(&dypair.1) { + (&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], false) } else { - if file.starts_with(&staticlib_prefix[..]) && - file.ends_with(&staticpair.1) { + if file.starts_with(&staticlib_prefix[..]) && file.ends_with(&staticpair.1) { staticlibs.push(CrateMismatch { path: path.to_path_buf(), - got: "static".to_string() + got: "static".to_string(), }); } - return FileDoesntMatch + return FileDoesntMatch; }; info!("lib candidate: {}", path.display()); let hash_str = hash.to_string(); let slot = candidates.entry(hash_str) - .or_insert_with(|| (FnvHashMap(), FnvHashMap())); + .or_insert_with(|| (FnvHashMap(), FnvHashMap())); let (ref mut rlibs, ref mut dylibs) = *slot; - fs::canonicalize(path).map(|p| { - if rlib { - rlibs.insert(p, kind); - } else { - dylibs.insert(p, kind); - } - FileMatches - }).unwrap_or(FileDoesntMatch) + fs::canonicalize(path) + .map(|p| { + if rlib { + rlibs.insert(p, kind); + } else { + dylibs.insert(p, kind); + } + FileMatches + }) + .unwrap_or(FileDoesntMatch) }); self.rejected_via_kind.extend(staticlibs); @@ -479,11 +498,12 @@ impl<'a> Context<'a> { let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot); let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot); if let Some((h, m)) = slot { - libraries.insert(h, Library { - dylib: dylib, - rlib: rlib, - metadata: m, - }); + libraries.insert(h, + Library { + dylib: dylib, + rlib: rlib, + metadata: m, + }); } } @@ -494,7 +514,9 @@ impl<'a> Context<'a> { 0 => None, 1 => Some(libraries.into_iter().next().unwrap().1), _ => { - let mut err = struct_span_err!(self.sess, self.span, E0464, + let mut err = struct_span_err!(self.sess, + self.span, + E0464, "multiple matching crates for `{}`", self.crate_name); err.note("candidates:"); @@ -521,8 +543,11 @@ impl<'a> Context<'a> { // read the metadata from it if `*slot` is `None`. If the metadata couldn't // be read, it is assumed that the file isn't a valid rust library (no // errors are emitted). - fn extract_one(&mut self, m: FnvHashMap<PathBuf, PathKind>, flavor: CrateFlavor, - slot: &mut Option<(Svh, MetadataBlob)>) -> Option<(PathBuf, PathKind)> { + fn extract_one(&mut self, + m: FnvHashMap<PathBuf, PathKind>, + flavor: CrateFlavor, + slot: &mut Option<(Svh, MetadataBlob)>) + -> Option<(PathBuf, PathKind)> { let mut ret: Option<(PathBuf, PathKind)> = None; let mut error = 0; @@ -532,9 +557,9 @@ impl<'a> Context<'a> { // read both, but reading dylib metadata is quite // slow. if m.is_empty() { - return None + return None; } else if m.len() == 1 { - return Some(m.into_iter().next().unwrap()) + return Some(m.into_iter().next().unwrap()); } } @@ -547,23 +572,28 @@ impl<'a> Context<'a> { (h, blob) } else { info!("metadata mismatch"); - continue + continue; } } Err(err) => { info!("no metadata found: {}", err); - continue + continue; } }; // If we see multiple hashes, emit an error about duplicate candidates. if slot.as_ref().map_or(false, |s| s.0 != hash) { - let mut e = struct_span_err!(self.sess, self.span, E0465, + let mut e = struct_span_err!(self.sess, + self.span, + E0465, "multiple {} candidates for `{}` found", - flavor, self.crate_name); + flavor, + self.crate_name); e.span_note(self.span, &format!(r"candidate #1: {}", - ret.as_ref().unwrap().0 - .display())); + ret.as_ref() + .unwrap() + .0 + .display())); if let Some(ref mut e) = err { e.emit(); } @@ -574,9 +604,10 @@ impl<'a> Context<'a> { if error > 0 { error += 1; err.as_mut().unwrap().span_note(self.span, - &format!(r"candidate #{}: {}", error, + &format!(r"candidate #{}: {}", + error, lib.display())); - continue + continue; } *slot = Some((hash, metadata)); ret = Some((lib, kind)); @@ -595,37 +626,39 @@ impl<'a> Context<'a> { let rustc_version = rustc_version(); if root.rustc_version != rustc_version { info!("Rejecting via version: expected {} got {}", - rustc_version, root.rustc_version); + rustc_version, + root.rustc_version); self.rejected_via_version.push(CrateMismatch { path: libpath.to_path_buf(), - got: root.rustc_version + got: root.rustc_version, }); return None; } if self.should_match_name { if self.crate_name != root.name { - info!("Rejecting via crate name"); return None; + info!("Rejecting via crate name"); + return None; } } if root.triple != self.triple { info!("Rejecting via crate triple: expected {} got {}", - self.triple, root.triple); + self.triple, + root.triple); self.rejected_via_triple.push(CrateMismatch { path: libpath.to_path_buf(), - got: root.triple + got: root.triple, }); return None; } if let Some(myhash) = self.hash { if *myhash != root.hash { - info!("Rejecting via hash: expected {} got {}", - *myhash, root.hash); + info!("Rejecting via hash: expected {} got {}", *myhash, root.hash); self.rejected_via_hash.push(CrateMismatch { path: libpath.to_path_buf(), - got: myhash.to_string() + got: myhash.to_string(), }); return None; } @@ -649,8 +682,8 @@ impl<'a> Context<'a> { (t.options.staticlib_prefix.clone(), t.options.staticlib_suffix.clone()) } - fn find_commandline_library<'b, LOCS> (&mut self, locs: LOCS) -> Option<Library> - where LOCS: Iterator<Item=&'b String> + fn find_commandline_library<'b, LOCS>(&mut self, locs: LOCS) -> Option<Library> + where LOCS: Iterator<Item = &'b String> { // First, filter out all libraries that look suspicious. We only accept // files which actually exist that have the correct naming scheme for @@ -663,30 +696,33 @@ impl<'a> Context<'a> { let locs = locs.map(|l| PathBuf::from(l)).filter(|loc| { if !loc.exists() { sess.err(&format!("extern location for {} does not exist: {}", - self.crate_name, loc.display())); + self.crate_name, + loc.display())); return false; } let file = match loc.file_name().and_then(|s| s.to_str()) { Some(file) => file, None => { sess.err(&format!("extern location for {} is not a file: {}", - self.crate_name, loc.display())); + self.crate_name, + loc.display())); return false; } }; if file.starts_with("lib") && file.ends_with(".rlib") { - return true + return true; } else { let (ref prefix, ref suffix) = dylibname; - if file.starts_with(&prefix[..]) && - file.ends_with(&suffix[..]) { - return true + if file.starts_with(&prefix[..]) && file.ends_with(&suffix[..]) { + return true; } } sess.struct_err(&format!("extern location for {} is of an unknown type: {}", - self.crate_name, loc.display())) + self.crate_name, + loc.display())) .help(&format!("file name should be lib*.rlib or {}*.{}", - dylibname.0, dylibname.1)) + dylibname.0, + dylibname.1)) .emit(); false }); @@ -695,11 +731,9 @@ impl<'a> Context<'a> { // there's at most one rlib and at most one dylib. for loc in locs { if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") { - rlibs.insert(fs::canonicalize(&loc).unwrap(), - PathKind::ExternFlag); + rlibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag); } else { - dylibs.insert(fs::canonicalize(&loc).unwrap(), - PathKind::ExternFlag); + dylibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag); } } }; @@ -709,13 +743,17 @@ impl<'a> Context<'a> { let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot); let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot); - if rlib.is_none() && dylib.is_none() { return None } + if rlib.is_none() && dylib.is_none() { + return None; + } match slot { - Some((_, metadata)) => Some(Library { - dylib: dylib, - rlib: rlib, - metadata: metadata, - }), + Some((_, metadata)) => { + Some(Library { + dylib: dylib, + rlib: rlib, + metadata: metadata, + }) + } None => None, } } @@ -728,9 +766,9 @@ pub fn note_crate_name(err: &mut DiagnosticBuilder, name: &str) { impl ArchiveMetadata { fn new(ar: ArchiveRO) -> Option<ArchiveMetadata> { let data = { - let section = ar.iter().filter_map(|s| s.ok()).find(|sect| { - sect.name() == Some(METADATA_FILENAME) - }); + let section = ar.iter() + .filter_map(|s| s.ok()) + .find(|sect| sect.name() == Some(METADATA_FILENAME)); match section { Some(s) => s.data() as *const [u8], None => { @@ -746,12 +784,14 @@ impl ArchiveMetadata { }) } - pub fn as_slice<'a>(&'a self) -> &'a [u8] { unsafe { &*self.data } } + pub fn as_slice<'a>(&'a self) -> &'a [u8] { + unsafe { &*self.data } + } } -fn verify_decompressed_encoding_version(blob: &MetadataBlob, filename: &Path) - -> Result<(), String> -{ +fn verify_decompressed_encoding_version(blob: &MetadataBlob, + filename: &Path) + -> Result<(), String> { if !blob.is_compatible() { Err((format!("incompatible metadata version found: '{}'", filename.display()))) @@ -761,16 +801,21 @@ fn verify_decompressed_encoding_version(blob: &MetadataBlob, filename: &Path) } // Just a small wrapper to time how long reading metadata takes. -fn get_metadata_section(target: &Target, flavor: CrateFlavor, filename: &Path) +fn get_metadata_section(target: &Target, + flavor: CrateFlavor, + filename: &Path) -> Result<MetadataBlob, String> { let start = Instant::now(); let ret = get_metadata_section_imp(target, flavor, filename); - info!("reading {:?} => {:?}", filename.file_name().unwrap(), + info!("reading {:?} => {:?}", + filename.file_name().unwrap(), start.elapsed()); - return ret + return ret; } -fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, filename: &Path) +fn get_metadata_section_imp(target: &Target, + flavor: CrateFlavor, + filename: &Path) -> Result<MetadataBlob, String> { if !filename.exists() { return Err(format!("no such file: '{}'", filename.display())); @@ -783,13 +828,11 @@ fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, filename: &Pat Some(ar) => ar, None => { debug!("llvm didn't like `{}`", filename.display()); - return Err(format!("failed to read rlib metadata: '{}'", - filename.display())); + return Err(format!("failed to read rlib metadata: '{}'", filename.display())); } }; return match ArchiveMetadata::new(archive).map(|ar| MetadataBlob::Archive(ar)) { - None => Err(format!("failed to read rlib metadata: '{}'", - filename.display())), + None => Err(format!("failed to read rlib metadata: '{}'", filename.display())), Some(blob) => { verify_decompressed_encoding_version(&blob, filename)?; Ok(blob) @@ -800,22 +843,19 @@ fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, filename: &Pat let buf = common::path2cstr(filename); let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()); if mb as isize == 0 { - return Err(format!("error reading library: '{}'", - filename.display())) + return Err(format!("error reading library: '{}'", filename.display())); } let of = match ObjectFile::new(mb) { Some(of) => of, _ => { - return Err((format!("provided path not an object file: '{}'", - filename.display()))) + return Err((format!("provided path not an object file: '{}'", filename.display()))) } }; let si = mk_section_iter(of.llof); while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { let mut name_buf = ptr::null(); let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf); - let name = slice::from_raw_parts(name_buf as *const u8, - name_len as usize).to_vec(); + let name = slice::from_raw_parts(name_buf as *const u8, name_len as usize).to_vec(); let name = String::from_utf8(name).unwrap(); debug!("get_metadata_section: name {}", name); if read_meta_section_name(target) == name { @@ -823,8 +863,7 @@ fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, filename: &Pat let csz = llvm::LLVMGetSectionSize(si.llsi) as usize; let cvbuf: *const u8 = cbuf as *const u8; let vlen = METADATA_HEADER.len(); - debug!("checking {} bytes of metadata-version stamp", - vlen); + debug!("checking {} bytes of metadata-version stamp", vlen); let minsz = cmp::min(vlen, csz); let buf0 = slice::from_raw_parts(cvbuf, minsz); let version_ok = buf0 == METADATA_HEADER; @@ -834,8 +873,7 @@ fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, filename: &Pat } let cvbuf1 = cvbuf.offset(vlen as isize); - debug!("inflating {} bytes of compressed metadata", - csz - vlen); + debug!("inflating {} bytes of compressed metadata", csz - vlen); let bytes = slice::from_raw_parts(cvbuf1, csz - vlen); match flate::inflate_bytes(bytes) { Ok(inflated) => { @@ -879,14 +917,15 @@ pub fn read_meta_section_name(_target: &Target) -> &'static str { } // A diagnostic function for dumping crate metadata to an output stream -pub fn list_file_metadata(target: &Target, path: &Path, - out: &mut io::Write) -> io::Result<()> { +pub fn list_file_metadata(target: &Target, path: &Path, out: &mut io::Write) -> io::Result<()> { let filename = path.file_name().unwrap().to_str().unwrap(); - let flavor = if filename.ends_with(".rlib") { CrateFlavor::Rlib } else { CrateFlavor::Dylib }; + let flavor = if filename.ends_with(".rlib") { + CrateFlavor::Rlib + } else { + CrateFlavor::Dylib + }; match get_metadata_section(target, flavor, path) { Ok(metadata) => metadata.list_crate_metadata(out), - Err(msg) => { - write!(out, "{}\n", msg) - } + Err(msg) => write!(out, "{}\n", msg), } } diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 0bb126ee0ff..3d1bd77d8bc 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -27,7 +27,8 @@ use syntax_pos::{self, Span}; use std::marker::PhantomData; pub fn rustc_version() -> String { - format!("rustc {}", option_env!("CFG_VERSION").unwrap_or("unknown version")) + format!("rustc {}", + option_env!("CFG_VERSION").unwrap_or("unknown version")) } /// Metadata encoding version. @@ -41,11 +42,8 @@ pub const METADATA_VERSION: u8 = 3; /// as a length of 0 by old compilers. /// /// This header is followed by the position of the `CrateRoot`. -pub const METADATA_HEADER: &'static [u8; 12] = &[ - 0, 0, 0, 0, - b'r', b'u', b's', b't', - 0, 0, 0, METADATA_VERSION -]; +pub const METADATA_HEADER: &'static [u8; 12] = + &[0, 0, 0, 0, b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION]; /// The shorthand encoding uses an enum's variant index `usize` /// and is offset by this value so it never matches a real variant. @@ -70,14 +68,14 @@ pub const SHORTHAND_OFFSET: usize = 0x80; #[must_use] pub struct Lazy<T> { pub position: usize, - _marker: PhantomData<T> + _marker: PhantomData<T>, } impl<T> Lazy<T> { pub fn with_position(position: usize) -> Lazy<T> { Lazy { position: position, - _marker: PhantomData + _marker: PhantomData, } } @@ -90,7 +88,9 @@ impl<T> Lazy<T> { impl<T> Copy for Lazy<T> {} impl<T> Clone for Lazy<T> { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } impl<T> serialize::UseSpecializedEncodable for Lazy<T> {} @@ -112,7 +112,7 @@ impl<T> serialize::UseSpecializedDecodable for Lazy<T> {} pub struct LazySeq<T> { pub len: usize, pub position: usize, - _marker: PhantomData<T> + _marker: PhantomData<T>, } impl<T> LazySeq<T> { @@ -124,7 +124,7 @@ impl<T> LazySeq<T> { LazySeq { len: len, position: position, - _marker: PhantomData + _marker: PhantomData, } } @@ -136,7 +136,9 @@ impl<T> LazySeq<T> { impl<T> Copy for LazySeq<T> {} impl<T> Clone for LazySeq<T> { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } impl<T> serialize::UseSpecializedEncodable for LazySeq<T> {} @@ -155,7 +157,7 @@ pub enum LazyState { /// Inside a metadata node, with a previous `Lazy` or `LazySeq`. /// The position is a conservative estimate of where that /// previous `Lazy` / `LazySeq` would end (see their comments). - Previous(usize) + Previous(usize), } #[derive(RustcEncodable, RustcDecodable)] @@ -185,13 +187,13 @@ pub struct CrateRoot { pub struct CrateDep { pub name: ast::Name, pub hash: hir::svh::Svh, - pub explicitly_linked: bool + pub explicitly_linked: bool, } #[derive(RustcEncodable, RustcDecodable)] pub struct TraitImpls { pub trait_id: (u32, DefIndex), - pub impls: LazySeq<DefIndex> + pub impls: LazySeq<DefIndex>, } #[derive(RustcEncodable, RustcDecodable)] @@ -199,7 +201,7 @@ pub struct MacroDef { pub name: ast::Name, pub attrs: Vec<ast::Attribute>, pub span: Span, - pub body: String + pub body: String, } #[derive(RustcEncodable, RustcDecodable)] @@ -219,7 +221,7 @@ pub struct Entry<'tcx> { pub predicates: Option<Lazy<ty::GenericPredicates<'tcx>>>, pub ast: Option<Lazy<astencode::Ast<'tcx>>>, - pub mir: Option<Lazy<mir::repr::Mir<'tcx>>> + pub mir: Option<Lazy<mir::Mir<'tcx>>>, } #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] @@ -245,18 +247,18 @@ pub enum EntryKind<'tcx> { DefaultImpl(Lazy<ImplData<'tcx>>), Method(Lazy<MethodData<'tcx>>), AssociatedType(AssociatedContainer), - AssociatedConst(AssociatedContainer) + AssociatedConst(AssociatedContainer), } #[derive(RustcEncodable, RustcDecodable)] pub struct ModData { - pub reexports: LazySeq<def::Export> + pub reexports: LazySeq<def::Export>, } #[derive(RustcEncodable, RustcDecodable)] pub struct FnData { pub constness: hir::Constness, - pub arg_names: LazySeq<ast::Name> + pub arg_names: LazySeq<ast::Name>, } #[derive(RustcEncodable, RustcDecodable)] @@ -266,7 +268,7 @@ pub struct VariantData { /// If this is a struct's only variant, this /// is the index of the "struct ctor" item. - pub struct_ctor: Option<DefIndex> + pub struct_ctor: Option<DefIndex>, } #[derive(RustcEncodable, RustcDecodable)] @@ -275,7 +277,7 @@ pub struct TraitData<'tcx> { pub paren_sugar: bool, pub has_default_impl: bool, pub trait_ref: Lazy<ty::TraitRef<'tcx>>, - pub super_predicates: Lazy<ty::GenericPredicates<'tcx>> + pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>, } #[derive(RustcEncodable, RustcDecodable)] @@ -283,7 +285,7 @@ pub struct ImplData<'tcx> { pub polarity: hir::ImplPolarity, pub parent_impl: Option<DefId>, pub coerce_unsized_kind: Option<ty::adjustment::CustomCoerceUnsized>, - pub trait_ref: Option<Lazy<ty::TraitRef<'tcx>>> + pub trait_ref: Option<Lazy<ty::TraitRef<'tcx>>>, } /// Describes whether the container of an associated item @@ -294,21 +296,17 @@ pub enum AssociatedContainer { TraitRequired, TraitWithDefault, ImplDefault, - ImplFinal + ImplFinal, } impl AssociatedContainer { pub fn with_def_id(&self, def_id: DefId) -> ty::ImplOrTraitItemContainer { match *self { AssociatedContainer::TraitRequired | - AssociatedContainer::TraitWithDefault => { - ty::TraitContainer(def_id) - } + AssociatedContainer::TraitWithDefault => ty::TraitContainer(def_id), AssociatedContainer::ImplDefault | - AssociatedContainer::ImplFinal => { - ty::ImplContainer(def_id) - } + AssociatedContainer::ImplFinal => ty::ImplContainer(def_id), } } @@ -318,7 +316,7 @@ impl AssociatedContainer { AssociatedContainer::TraitWithDefault | AssociatedContainer::ImplDefault | - AssociatedContainer::ImplFinal => true + AssociatedContainer::ImplFinal => true, } } @@ -328,7 +326,7 @@ impl AssociatedContainer { AssociatedContainer::TraitWithDefault | AssociatedContainer::ImplDefault => hir::Defaultness::Default, - AssociatedContainer::ImplFinal => hir::Defaultness::Final + AssociatedContainer::ImplFinal => hir::Defaultness::Final, } } } @@ -337,11 +335,11 @@ impl AssociatedContainer { pub struct MethodData<'tcx> { pub fn_data: FnData, pub container: AssociatedContainer, - pub explicit_self: Lazy<ty::ExplicitSelfCategory<'tcx>> + pub explicit_self: Lazy<ty::ExplicitSelfCategory<'tcx>>, } #[derive(RustcEncodable, RustcDecodable)] pub struct ClosureData<'tcx> { pub kind: ty::ClosureKind, - pub ty: Lazy<ty::ClosureTy<'tcx>> + pub ty: Lazy<ty::ClosureTy<'tcx>>, } diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index 34d79732646..b53f8c4da86 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -10,7 +10,7 @@ use build::{BlockAnd, BlockAndExtension, Builder}; use hair::*; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc::hir; impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs index 026a79b32b8..9f612175e5d 100644 --- a/src/librustc_mir/build/cfg.rs +++ b/src/librustc_mir/build/cfg.rs @@ -14,7 +14,7 @@ //! Routines for manipulating the control-flow graph. use build::CFG; -use rustc::mir::repr::*; +use rustc::mir::*; impl<'tcx> CFG<'tcx> { pub fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> { diff --git a/src/librustc_mir/build/expr/as_constant.rs b/src/librustc_mir/build/expr/as_constant.rs index a08d14d9e20..6230123a9ca 100644 --- a/src/librustc_mir/build/expr/as_constant.rs +++ b/src/librustc_mir/build/expr/as_constant.rs @@ -12,7 +12,7 @@ use build::Builder; use hair::*; -use rustc::mir::repr::*; +use rustc::mir::*; impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Compile `expr`, yielding a compile-time constant. Assumes that diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs index 118b23cf987..58abaa0c484 100644 --- a/src/librustc_mir/build/expr/as_lvalue.rs +++ b/src/librustc_mir/build/expr/as_lvalue.rs @@ -13,7 +13,7 @@ use build::{BlockAnd, BlockAndExtension, Builder}; use build::expr::category::Category; use hair::*; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc_data_structures::indexed_vec::Idx; diff --git a/src/librustc_mir/build/expr/as_operand.rs b/src/librustc_mir/build/expr/as_operand.rs index beb9ca256ab..09cdcc74ef6 100644 --- a/src/librustc_mir/build/expr/as_operand.rs +++ b/src/librustc_mir/build/expr/as_operand.rs @@ -13,7 +13,7 @@ use build::{BlockAnd, BlockAndExtension, Builder}; use build::expr::category::Category; use hair::*; -use rustc::mir::repr::*; +use rustc::mir::*; impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Compile `expr` into a value that can be used as an operand. diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index dcb301cab00..490f675c3d5 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -22,7 +22,7 @@ use hair::*; use rustc_const_math::{ConstInt, ConstIsize}; use rustc::middle::const_val::ConstVal; use rustc::ty; -use rustc::mir::repr::*; +use rustc::mir::*; use syntax::ast; use syntax_pos::Span; diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index 85128cbbbaf..fb12e08affd 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -13,7 +13,7 @@ use build::{BlockAnd, BlockAndExtension, Builder}; use build::expr::category::Category; use hair::*; -use rustc::mir::repr::*; +use rustc::mir::*; impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Compile `expr` into a fresh temporary. This is used when building diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 58265b5b0d3..5fa08442221 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -14,7 +14,7 @@ use build::{BlockAnd, BlockAndExtension, Builder}; use build::expr::category::{Category, RvalueFunc}; use hair::*; use rustc::ty; -use rustc::mir::repr::*; +use rustc::mir::*; impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Compile `expr`, storing the result into `destination`, which diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir/build/expr/stmt.rs index 9448527e6e6..4a1926e7c57 100644 --- a/src/librustc_mir/build/expr/stmt.rs +++ b/src/librustc_mir/build/expr/stmt.rs @@ -12,7 +12,7 @@ use build::{BlockAnd, BlockAndExtension, Builder}; use build::scope::LoopScope; use hair::*; use rustc::middle::region::CodeExtent; -use rustc::mir::repr::*; +use rustc::mir::*; use syntax_pos::Span; impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { diff --git a/src/librustc_mir/build/into.rs b/src/librustc_mir/build/into.rs index 17ccb701c2b..5c133780e43 100644 --- a/src/librustc_mir/build/into.rs +++ b/src/librustc_mir/build/into.rs @@ -16,7 +16,7 @@ use build::{BlockAnd, Builder}; use hair::*; -use rustc::mir::repr::*; +use rustc::mir::*; pub trait EvalInto<'tcx> { fn eval_into<'a, 'gcx>(self, diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index a9ea82140b5..727e634ef92 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -18,7 +18,7 @@ use rustc_data_structures::fnv::FnvHashMap; use rustc_data_structures::bitvec::BitVector; use rustc::middle::const_val::ConstVal; use rustc::ty::{AdtDef, Ty}; -use rustc::mir::repr::*; +use rustc::mir::*; use hair::*; use syntax::ast::{Name, NodeId}; use syntax_pos::Span; diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index 8392248e3f2..71282dcf0ba 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -25,7 +25,7 @@ use build::{BlockAnd, BlockAndExtension, Builder}; use build::matches::{Binding, MatchPair, Candidate}; use hair::*; -use rustc::mir::repr::*; +use rustc::mir::*; use std::mem; diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 78a1604a5cb..5984b0f7893 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -22,7 +22,7 @@ use rustc_data_structures::fnv::FnvHashMap; use rustc_data_structures::bitvec::BitVector; use rustc::middle::const_val::ConstVal; use rustc::ty::{self, Ty}; -use rustc::mir::repr::*; +use rustc::mir::*; use syntax_pos::Span; use std::cmp::Ordering; diff --git a/src/librustc_mir/build/matches/util.rs b/src/librustc_mir/build/matches/util.rs index 53ebf6fceb5..a013875b311 100644 --- a/src/librustc_mir/build/matches/util.rs +++ b/src/librustc_mir/build/matches/util.rs @@ -11,7 +11,7 @@ use build::Builder; use build::matches::MatchPair; use hair::*; -use rustc::mir::repr::*; +use rustc::mir::*; use std::u32; impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs index 4bc51c3a625..a5f51ef35b7 100644 --- a/src/librustc_mir/build/misc.rs +++ b/src/librustc_mir/build/misc.rs @@ -17,7 +17,7 @@ use rustc_const_math::{ConstInt, ConstUsize, ConstIsize}; use rustc::middle::const_val::ConstVal; use rustc::ty::{self, Ty}; -use rustc::mir::repr::*; +use rustc::mir::*; use syntax::ast; use syntax_pos::Span; diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index a7249677e01..d6fcc79a9a2 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -13,7 +13,7 @@ use hair::Pattern; use rustc::middle::region::{CodeExtent, CodeExtentData, ROOT_CODE_EXTENT}; use rustc::ty::{self, Ty}; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc::util::nodemap::NodeMap; use rustc::hir; use syntax::abi::Abi; diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 185668ff767..af8170a1b8f 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -91,7 +91,7 @@ use rustc::middle::region::{CodeExtent, CodeExtentData}; use rustc::middle::lang_items; use rustc::ty::subst::{Kind, Subst}; use rustc::ty::{Ty, TyCtxt}; -use rustc::mir::repr::*; +use rustc::mir::*; use syntax_pos::Span; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::fnv::FnvHashMap; diff --git a/src/librustc_mir/def_use.rs b/src/librustc_mir/def_use.rs index 343d802119e..d20d50c5611 100644 --- a/src/librustc_mir/def_use.rs +++ b/src/librustc_mir/def_use.rs @@ -10,7 +10,7 @@ //! Def-use analysis. -use rustc::mir::repr::{Local, Location, Lvalue, Mir}; +use rustc::mir::{Local, Location, Lvalue, Mir}; use rustc::mir::visit::{LvalueContext, MutVisitor, Visitor}; use rustc_data_structures::indexed_vec::IndexVec; use std::marker::PhantomData; diff --git a/src/librustc_mir/graphviz.rs b/src/librustc_mir/graphviz.rs index 1c1f0ca7902..dd4dd4699d8 100644 --- a/src/librustc_mir/graphviz.rs +++ b/src/librustc_mir/graphviz.rs @@ -10,8 +10,7 @@ use dot; use rustc::hir::def_id::DefId; -use rustc::mir::repr::*; -use rustc::mir::mir_map::MirMap; +use rustc::mir::*; use rustc::ty::TyCtxt; use std::fmt::Debug; use std::io::{self, Write}; @@ -22,14 +21,13 @@ use rustc_data_structures::indexed_vec::Idx; /// Write a graphviz DOT graph of a list of MIRs. pub fn write_mir_graphviz<'a, 'b, 'tcx, W, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>, iter: I, - mir_map: &MirMap<'tcx>, w: &mut W) -> io::Result<()> where W: Write, I: Iterator<Item=DefId> { for def_id in iter { let nodeid = tcx.map.as_local_node_id(def_id).unwrap(); - let mir = &mir_map.map[&def_id]; + let mir = &tcx.item_mir(def_id); writeln!(w, "digraph Mir_{} {{", nodeid)?; diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 45c49a4627f..1b324ac3132 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -21,7 +21,7 @@ use rustc_const_eval as const_eval; use rustc::middle::region::CodeExtent; use rustc::ty::{self, AdtKind, VariantDef, Ty}; use rustc::ty::cast::CastKind as TyCastKind; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc::hir; use syntax::ptr::P; diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index f87e0acaa4c..678db1e544c 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -16,7 +16,7 @@ */ use hair::*; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc::mir::transform::MirSource; use rustc::middle::const_val::ConstVal; diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 49a592b07fb..e211334e547 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -14,7 +14,7 @@ //! unit-tested and separated from the Rust source and compiler data //! structures. -use rustc::mir::repr::{BinOp, BorrowKind, Field, Literal, UnOp, TypedConstVal}; +use rustc::mir::{BinOp, BorrowKind, Field, Literal, UnOp, TypedConstVal}; use rustc::hir::def_id::DefId; use rustc::middle::region::CodeExtent; use rustc::ty::subst::Substs; diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index 2dcefcc12f6..b0e2d6e73d3 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -19,13 +19,12 @@ use build; use rustc::dep_graph::DepNode; use rustc::hir::def_id::DefId; -use rustc::mir::repr::Mir; +use rustc::mir::Mir; use rustc::mir::transform::MirSource; use rustc::mir::visit::MutVisitor; use pretty; use hair::cx::Cx; -use rustc::mir::mir_map::MirMap; use rustc::infer::InferCtxtBuilder; use rustc::traits::Reveal; use rustc::ty::{self, Ty, TyCtxt}; @@ -37,16 +36,10 @@ use syntax_pos::Span; use std::mem; -pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> MirMap<'tcx> { - let mut map = MirMap::new(tcx.dep_graph.clone()); - { - let mut dump = BuildMir { - tcx: tcx, - map: &mut map, - }; - tcx.visit_all_items_in_krate(DepNode::Mir, &mut dump); - } - map +pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { + tcx.visit_all_items_in_krate(DepNode::Mir, &mut BuildMir { + tcx: tcx + }); } /// A pass to lift all the types and substitutions in a Mir @@ -83,8 +76,7 @@ impl<'a, 'gcx: 'tcx, 'tcx> MutVisitor<'tcx> for GlobalizeMir<'a, 'gcx> { // BuildMir -- walks a crate, looking for fn items and methods to build MIR from struct BuildMir<'a, 'tcx: 'a> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, - map: &'a mut MirMap<'tcx>, + tcx: TyCtxt<'a, 'tcx, 'tcx> } /// Helper type of a temporary returned by BuildMir::cx(...). @@ -93,8 +85,7 @@ struct BuildMir<'a, 'tcx: 'a> { struct CxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { src: MirSource, def_id: DefId, - infcx: InferCtxtBuilder<'a, 'gcx, 'tcx>, - map: &'a mut MirMap<'gcx>, + infcx: InferCtxtBuilder<'a, 'gcx, 'tcx> } impl<'a, 'gcx, 'tcx> BuildMir<'a, 'gcx> { @@ -104,8 +95,7 @@ impl<'a, 'gcx, 'tcx> BuildMir<'a, 'gcx> { CxBuilder { src: src, infcx: self.tcx.infer_ctxt(None, Some(param_env), Reveal::NotSpecializable), - def_id: def_id, - map: self.map + def_id: def_id } } } @@ -114,13 +104,14 @@ impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> { fn build<F>(&'tcx mut self, f: F) where F: for<'b> FnOnce(Cx<'b, 'gcx, 'tcx>) -> (Mir<'tcx>, build::ScopeAuxiliaryVec) { - let src = self.src; - let mir = self.infcx.enter(|infcx| { + let (src, def_id) = (self.src, self.def_id); + self.infcx.enter(|infcx| { let (mut mir, scope_auxiliary) = f(Cx::new(&infcx, src)); // Convert the Mir to global types. + let tcx = infcx.tcx.global_tcx(); let mut globalizer = GlobalizeMir { - tcx: infcx.tcx.global_tcx(), + tcx: tcx, span: mir.span }; globalizer.visit_mir(&mut mir); @@ -128,13 +119,11 @@ impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> { mem::transmute::<Mir, Mir<'gcx>>(mir) }; - pretty::dump_mir(infcx.tcx.global_tcx(), "mir_map", &0, - src, &mir, Some(&scope_auxiliary)); + pretty::dump_mir(tcx, "mir_map", &0, src, &mir, Some(&scope_auxiliary)); - mir + let mir = tcx.alloc_mir(mir); + assert!(tcx.mir_map.borrow_mut().insert(def_id, mir).is_none()); }); - - assert!(self.map.map.insert(self.def_id, mir).is_none()) } } diff --git a/src/librustc_mir/pretty.rs b/src/librustc_mir/pretty.rs index 5c88c898621..d2fc8aeaa2e 100644 --- a/src/librustc_mir/pretty.rs +++ b/src/librustc_mir/pretty.rs @@ -11,8 +11,7 @@ use build::{ScopeAuxiliaryVec, ScopeId}; use rustc::hir; use rustc::hir::def_id::DefId; -use rustc::mir::repr::*; -use rustc::mir::mir_map::MirMap; +use rustc::mir::*; use rustc::mir::transform::MirSource; use rustc::ty::TyCtxt; use rustc_data_structures::fnv::FnvHashMap; @@ -90,14 +89,13 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, /// Write out a human-readable textual representation for the given MIR. pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>, iter: I, - mir_map: &MirMap<'tcx>, w: &mut Write) -> io::Result<()> where I: Iterator<Item=DefId>, 'tcx: 'a { let mut first = true; for def_id in iter { - let mir = &mir_map.map[&def_id]; + let mir = &tcx.item_mir(def_id); if first { first = false; diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs index c028504d6f9..89e644e4fb0 100644 --- a/src/librustc_mir/transform/add_call_guards.rs +++ b/src/librustc_mir/transform/add_call_guards.rs @@ -9,7 +9,7 @@ // except according to those terms. use rustc::ty::TyCtxt; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc::mir::transform::{MirPass, MirSource, Pass}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index 783162cd558..8c8c42a1c76 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/src/librustc_mir/transform/copy_prop.rs @@ -30,7 +30,7 @@ //! future. use def_use::DefUseAnalysis; -use rustc::mir::repr::{Constant, Local, Location, Lvalue, Mir, Operand, Rvalue, StatementKind}; +use rustc::mir::{Constant, Local, Location, Lvalue, Mir, Operand, Rvalue, StatementKind}; use rustc::mir::transform::{MirPass, MirSource, Pass}; use rustc::mir::visit::MutVisitor; use rustc::ty::TyCtxt; diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs index 198a6d256bc..fcdeae6d6c0 100644 --- a/src/librustc_mir/transform/deaggregator.rs +++ b/src/librustc_mir/transform/deaggregator.rs @@ -9,7 +9,7 @@ // except according to those terms. use rustc::ty::TyCtxt; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc::mir::transform::{MirPass, MirSource, Pass}; use rustc_data_structures::indexed_vec::Idx; diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs index 694b017bbd7..b8fd9fb12ab 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/src/librustc_mir/transform/dump_mir.rs @@ -13,7 +13,7 @@ use std::fmt; use rustc::ty::TyCtxt; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc::mir::transform::{Pass, MirPass, MirPassHook, MirSource}; use pretty; diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs index 485ca3ea84a..cebd9dd9668 100644 --- a/src/librustc_mir/transform/erase_regions.rs +++ b/src/librustc_mir/transform/erase_regions.rs @@ -14,7 +14,7 @@ use rustc::ty::subst::Substs; use rustc::ty::{Ty, TyCtxt}; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc::mir::visit::MutVisitor; use rustc::mir::transform::{MirPass, MirSource, Pass}; diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index b4159af6f07..a01724d6d0e 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -10,7 +10,7 @@ //! Performs various peephole optimizations. -use rustc::mir::repr::{Location, Lvalue, Mir, Operand, ProjectionElem, Rvalue, Local}; +use rustc::mir::{Location, Lvalue, Mir, Operand, ProjectionElem, Rvalue, Local}; use rustc::mir::transform::{MirPass, MirSource, Pass}; use rustc::mir::visit::{MutVisitor, Visitor}; use rustc::ty::TyCtxt; diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs index 32fddd293ca..6ef5720b330 100644 --- a/src/librustc_mir/transform/no_landing_pads.rs +++ b/src/librustc_mir/transform/no_landing_pads.rs @@ -12,7 +12,7 @@ //! specified. use rustc::ty::TyCtxt; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc::mir::visit::MutVisitor; use rustc::mir::transform::{Pass, MirPass, MirSource}; diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 9afc97d1e31..41698574e0f 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -22,7 +22,7 @@ //! initialization and can otherwise silence errors, if //! move analysis runs after promotion on broken MIR. -use rustc::mir::repr::*; +use rustc::mir::*; use rustc::mir::visit::{LvalueContext, MutVisitor, Visitor}; use rustc::mir::traversal::ReversePostorder; use rustc::ty::TyCtxt; diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index b00a88093d7..b33a7060e37 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -16,7 +16,6 @@ use rustc_data_structures::bitvec::BitVector; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; -use rustc::dep_graph::DepNode; use rustc::hir; use rustc::hir::map as hir_map; use rustc::hir::def_id::DefId; @@ -25,10 +24,9 @@ use rustc::hir::map::blocks::FnLikeNode; use rustc::traits::{self, Reveal}; use rustc::ty::{self, TyCtxt, Ty}; use rustc::ty::cast::CastTy; -use rustc::mir::repr::*; -use rustc::mir::mir_map::MirMap; -use rustc::mir::traversal::{self, ReversePostorder}; -use rustc::mir::transform::{Pass, MirMapPass, MirPassHook, MirSource}; +use rustc::mir::*; +use rustc::mir::traversal::ReversePostorder; +use rustc::mir::transform::{Pass, MirPass, MirSource}; use rustc::mir::visit::{LvalueContext, Visitor}; use rustc::util::nodemap::DefIdMap; use syntax::abi::Abi; @@ -142,7 +140,6 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, param_env: ty::ParameterEnvironment<'tcx>, qualif_map: &'a mut DefIdMap<Qualif>, - mir_map: Option<&'a MirMap<'tcx>>, temp_qualif: IndexVec<Local, Option<Qualif>>, return_qualif: Option<Qualif>, qualif: Qualif, @@ -155,7 +152,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParameterEnvironment<'tcx>, qualif_map: &'a mut DefIdMap<Qualif>, - mir_map: Option<&'a MirMap<'tcx>>, def_id: DefId, mir: &'a Mir<'tcx>, mode: Mode) @@ -172,7 +168,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { tcx: tcx, param_env: param_env, qualif_map: qualif_map, - mir_map: mir_map, temp_qualif: IndexVec::from_elem(None, &mir.local_decls), return_qualif: None, qualif: Qualif::empty(), @@ -595,7 +590,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } else { let qualif = qualify_const_item_cached(self.tcx, self.qualif_map, - self.mir_map, def_id); self.add(qualif); } @@ -949,7 +943,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { fn qualify_const_item_cached<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, qualif_map: &mut DefIdMap<Qualif>, - mir_map: Option<&MirMap<'tcx>>, def_id: DefId) -> Qualif { match qualif_map.entry(def_id) { @@ -960,124 +953,100 @@ fn qualify_const_item_cached<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } - let extern_mir; - let param_env_and_mir = if def_id.is_local() { - mir_map.and_then(|map| map.map.get(&def_id)).map(|mir| { - let node_id = tcx.map.as_local_node_id(def_id).unwrap(); - (ty::ParameterEnvironment::for_item(tcx, node_id), mir) - }) - } else if let Some(mir) = tcx.sess.cstore.maybe_get_item_mir(tcx, def_id) { - // These should only be monomorphic constants. - extern_mir = mir; - Some((tcx.empty_parameter_environment(), &extern_mir)) + let param_env = if def_id.is_local() { + let node_id = tcx.map.as_local_node_id(def_id).unwrap(); + ty::ParameterEnvironment::for_item(tcx, node_id) } else { - None + // These should only be monomorphic constants. + tcx.empty_parameter_environment() }; - let (param_env, mir) = param_env_and_mir.unwrap_or_else(|| { - bug!("missing constant MIR for {}", tcx.item_path_str(def_id)) - }); - - let mut qualifier = Qualifier::new(tcx, param_env, qualif_map, mir_map, - def_id, mir, Mode::Const); + let mir = &tcx.item_mir(def_id); + let mut qualifier = Qualifier::new(tcx, param_env, qualif_map, def_id, mir, Mode::Const); let qualif = qualifier.qualify_const(); qualifier.qualif_map.insert(def_id, qualif); qualif } -pub struct QualifyAndPromoteConstants; +#[derive(Default)] +pub struct QualifyAndPromoteConstants { + qualif_map: DefIdMap<Qualif> +} impl Pass for QualifyAndPromoteConstants {} -impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants { - fn run_pass<'a>(&mut self, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - map: &mut MirMap<'tcx>, - hooks: &mut [Box<for<'s> MirPassHook<'s>>]) { - let mut qualif_map = DefIdMap(); - - // First, visit `const` items, potentially recursing, to get - // accurate MUTABLE_INTERIOR and NEEDS_DROP qualifications. - let keys = map.map.keys(); - for &def_id in &keys { - let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id)); - let id = tcx.map.as_local_node_id(def_id).unwrap(); - let src = MirSource::from_node(tcx, id); - if let MirSource::Const(_) = src { - qualify_const_item_cached(tcx, &mut qualif_map, Some(map), def_id); +impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants { + fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, + src: MirSource, mir: &mut Mir<'tcx>) { + let id = src.item_id(); + let def_id = tcx.map.local_def_id(id); + let mode = match src { + MirSource::Fn(_) => { + if is_const_fn(tcx, def_id) { + Mode::ConstFn + } else { + Mode::Fn + } } - } - - // Then, handle everything else, without recursing, - // as the MIR map is not shared, since promotion - // in functions (including `const fn`) mutates it. - for &def_id in &keys { - let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id)); - let id = tcx.map.as_local_node_id(def_id).unwrap(); - let src = MirSource::from_node(tcx, id); - let mode = match src { - MirSource::Fn(_) => { - if is_const_fn(tcx, def_id) { - Mode::ConstFn - } else { - Mode::Fn + MirSource::Const(_) => { + match self.qualif_map.entry(def_id) { + Entry::Occupied(_) => return, + Entry::Vacant(entry) => { + // Guard against `const` recursion. + entry.insert(Qualif::RECURSIVE); } } - MirSource::Const(_) => continue, - MirSource::Static(_, hir::MutImmutable) => Mode::Static, - MirSource::Static(_, hir::MutMutable) => Mode::StaticMut, - MirSource::Promoted(..) => bug!() - }; - let param_env = ty::ParameterEnvironment::for_item(tcx, id); - - let mir = map.map.get_mut(&def_id).unwrap(); - for hook in &mut *hooks { - hook.on_mir_pass(tcx, src, mir, self, false); + Mode::Const } - - if mode == Mode::Fn || mode == Mode::ConstFn { - // This is ugly because Qualifier holds onto mir, - // which can't be mutated until its scope ends. - let (temps, candidates) = { - let mut qualifier = Qualifier::new(tcx, param_env, &mut qualif_map, - None, def_id, mir, mode); - if mode == Mode::ConstFn { - // Enforce a constant-like CFG for `const fn`. - qualifier.qualify_const(); - } else { - while let Some((bb, data)) = qualifier.rpo.next() { - qualifier.visit_basic_block_data(bb, data); - } + MirSource::Static(_, hir::MutImmutable) => Mode::Static, + MirSource::Static(_, hir::MutMutable) => Mode::StaticMut, + MirSource::Promoted(..) => return + }; + let param_env = ty::ParameterEnvironment::for_item(tcx, id); + + if mode == Mode::Fn || mode == Mode::ConstFn { + // This is ugly because Qualifier holds onto mir, + // which can't be mutated until its scope ends. + let (temps, candidates) = { + let mut qualifier = Qualifier::new(tcx, param_env, + &mut self.qualif_map, + def_id, mir, mode); + if mode == Mode::ConstFn { + // Enforce a constant-like CFG for `const fn`. + qualifier.qualify_const(); + } else { + while let Some((bb, data)) = qualifier.rpo.next() { + qualifier.visit_basic_block_data(bb, data); } + } - (qualifier.temp_promotion_state, - qualifier.promotion_candidates) - }; + (qualifier.temp_promotion_state, qualifier.promotion_candidates) + }; - // Do the actual promotion, now that we know what's viable. - promote_consts::promote_candidates(mir, tcx, temps, candidates); - } else { - let mut qualifier = Qualifier::new(tcx, param_env, &mut qualif_map, - None, def_id, mir, mode); - qualifier.qualify_const(); - } + // Do the actual promotion, now that we know what's viable. + promote_consts::promote_candidates(mir, tcx, temps, candidates); + } else { + let mut qualifier = Qualifier::new(tcx, param_env, + &mut self.qualif_map, + def_id, mir, mode); + let qualif = qualifier.qualify_const(); - for hook in &mut *hooks { - hook.on_mir_pass(tcx, src, mir, self, true); + if mode == Mode::Const { + qualifier.qualif_map.insert(def_id, qualif); } + } - // Statics must be Sync. - if mode == Mode::Static { - let ty = mir.return_ty; - tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| { - let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic); - let mut fulfillment_cx = traits::FulfillmentContext::new(); - fulfillment_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause); - if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) { - infcx.report_fulfillment_errors(&err); - } - }); - } + // Statics must be Sync. + if mode == Mode::Static { + let ty = mir.return_ty; + tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| { + let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic); + let mut fulfillment_cx = traits::FulfillmentContext::new(); + fulfillment_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause); + if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) { + infcx.report_fulfillment_errors(&err); + } + }); } } } diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs index 407e2161610..8759a340d7e 100644 --- a/src/librustc_mir/transform/simplify_branches.rs +++ b/src/librustc_mir/transform/simplify_branches.rs @@ -13,7 +13,7 @@ use rustc::ty::TyCtxt; use rustc::middle::const_val::ConstVal; use rustc::mir::transform::{MirPass, MirSource, Pass}; -use rustc::mir::repr::*; +use rustc::mir::*; use std::fmt; diff --git a/src/librustc_mir/transform/simplify_cfg.rs b/src/librustc_mir/transform/simplify_cfg.rs index ca8556496fa..1a8a5fa18cf 100644 --- a/src/librustc_mir/transform/simplify_cfg.rs +++ b/src/librustc_mir/transform/simplify_cfg.rs @@ -35,9 +35,8 @@ use rustc_data_structures::bitvec::BitVector; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc::ty::TyCtxt; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc::mir::transform::{MirPass, MirSource, Pass}; -use rustc::mir::traversal; use std::fmt; pub struct SimplifyCfg<'a> { label: &'a str } diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 7a682292429..9d3afe541cc 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -15,10 +15,10 @@ use rustc::infer::{self, InferCtxt, InferOk}; use rustc::traits::{self, Reveal}; use rustc::ty::fold::TypeFoldable; use rustc::ty::{self, Ty, TyCtxt, TypeVariants}; -use rustc::mir::repr::*; +use rustc::mir::*; use rustc::mir::tcx::LvalueTy; use rustc::mir::transform::{MirPass, MirSource, Pass}; -use rustc::mir::visit::{self, Visitor}; +use rustc::mir::visit::Visitor; use std::fmt; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 5096a574e2b..828efbf3731 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -190,8 +190,16 @@ impl<'a> Visitor for AstValidator<'a> { } ItemKind::Trait(.., ref trait_items) => { for trait_item in trait_items { - if let TraitItemKind::Method(ref sig, _) = trait_item.node { + if let TraitItemKind::Method(ref sig, ref block) = trait_item.node { self.check_trait_fn_not_const(sig.constness); + if block.is_none() { + self.check_decl_no_pat(&sig.decl, |span, _| { + self.session.add_lint(lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY, + trait_item.id, span, + "patterns aren't allowed in methods \ + without bodies".to_string()); + }); + } } } } diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index ee731dd042e..8ad4d7f57a6 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -565,9 +565,11 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node } } hir::ExprStruct(..) => { - // unsafe_cell_type doesn't necessarily exist with no_core - if Some(v.tcx.expect_def(e.id).def_id()) == v.tcx.lang_items.unsafe_cell_type() { - v.add_qualif(ConstQualif::MUTABLE_MEM); + if let ty::TyAdt(adt, ..) = v.tcx.expr_ty(e).sty { + // unsafe_cell_type doesn't necessarily exist with no_core + if Some(adt.did) == v.tcx.lang_items.unsafe_cell_type() { + v.add_qualif(ConstQualif::MUTABLE_MEM); + } } } diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs index 669df3ad950..4438241999a 100644 --- a/src/librustc_plugin/load.rs +++ b/src/librustc_plugin/load.rs @@ -47,7 +47,7 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate, crate_name: &str, addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrar> { - let mut loader = PluginLoader::new(sess, cstore, crate_name, krate.config.clone()); + let mut loader = PluginLoader::new(sess, cstore, crate_name); // do not report any error now. since crate attributes are // not touched by expansion, every use of plugin without @@ -89,14 +89,10 @@ pub fn load_plugins(sess: &Session, } impl<'a> PluginLoader<'a> { - fn new(sess: &'a Session, - cstore: &'a CStore, - crate_name: &str, - crate_config: ast::CrateConfig) - -> PluginLoader<'a> { + fn new(sess: &'a Session, cstore: &'a CStore, crate_name: &str) -> Self { PluginLoader { sess: sess, - reader: CrateLoader::new(sess, cstore, crate_name, crate_config), + reader: CrateLoader::new(sess, cstore, crate_name), plugins: vec![], } } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index f2a5aedbb3a..1fb5db05dd5 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -860,31 +860,6 @@ match (A, B, C) { ``` "##, -E0422: r##" -You are trying to use an identifier that is either undefined or not a struct. - -Erroneous code example: - -``` compile_fail,E0422 -fn main () { - let x = Foo { x: 1, y: 2 }; -} -``` - -In this case, `Foo` is undefined, so it inherently isn't anything, and -definitely not a struct. - -```compile_fail,E0422 -fn main () { - let foo = 1; - let x = foo { x: 1, y: 2 }; -} -``` - -In this case, `foo` is defined, but is not a struct, so Rust can't use it as -one. -"##, - E0423: r##" A `struct` variant name was used like a function name. @@ -1503,6 +1478,7 @@ register_diagnostics! { // E0419, merged into 531 // E0420, merged into 532 // E0421, merged into 531 +// E0422, merged into 531/532 E0531, // unresolved pattern path kind `name` E0532, // expected pattern path kind, found another pattern path kind // E0427, merged into 530 diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 856eb348eae..0b382fcbfdd 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -129,8 +129,6 @@ enum ResolutionError<'a> { IdentifierBoundMoreThanOnceInParameterList(&'a str), /// error E0416: identifier is bound more than once in the same pattern IdentifierBoundMoreThanOnceInSamePattern(&'a str), - /// error E0422: does not name a struct - DoesNotNameAStruct(&'a str), /// error E0423: is a struct variant name, but this expression uses it like a function name StructVariantUsedAsFunction(&'a str), /// error E0424: `self` is not available in a static method @@ -336,15 +334,6 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, err.span_label(span, &format!("used in a pattern more than once")); err } - ResolutionError::DoesNotNameAStruct(name) => { - let mut err = struct_span_err!(resolver.session, - span, - E0422, - "`{}` does not name a structure", - name); - err.span_label(span, &format!("not a structure")); - err - } ResolutionError::StructVariantUsedAsFunction(path_name) => { let mut err = struct_span_err!(resolver.session, span, @@ -1412,7 +1401,7 @@ impl<'a> Resolver<'a> { format!("Did you mean `{}{}`?", prefix, path_str) } - None => format!("Maybe a missing `extern crate {}`?", segment_name), + None => format!("Maybe a missing `extern crate {};`?", segment_name), } } else { format!("Could not find `{}` in `{}`", segment_name, module_name) @@ -2383,6 +2372,18 @@ impl<'a> Resolver<'a> { self.record_def(pat_id, resolution); } + fn resolve_struct_path(&mut self, node_id: NodeId, path: &Path) { + // Resolution logic is equivalent for expressions and patterns, + // reuse `resolve_pattern_path` for both. + self.resolve_pattern_path(node_id, None, path, TypeNS, |def| { + match def { + Def::Struct(..) | Def::Union(..) | Def::Variant(..) | + Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => true, + _ => false, + } + }, "struct, variant or union type"); + } + fn resolve_pattern(&mut self, pat: &Pat, pat_src: PatternSource, @@ -2460,13 +2461,7 @@ impl<'a> Resolver<'a> { } PatKind::Struct(ref path, ..) => { - self.resolve_pattern_path(pat.id, None, path, TypeNS, |def| { - match def { - Def::Struct(..) | Def::Union(..) | Def::Variant(..) | - Def::TyAlias(..) | Def::AssociatedTy(..) => true, - _ => false, - } - }, "variant, struct or type alias"); + self.resolve_struct_path(pat.id, path); } _ => {} @@ -3024,23 +3019,7 @@ impl<'a> Resolver<'a> { } ExprKind::Struct(ref path, ..) => { - // Resolve the path to the structure it goes to. We don't - // check to ensure that the path is actually a structure; that - // is checked later during typeck. - match self.resolve_path(expr.id, path, 0, TypeNS) { - Ok(definition) => self.record_def(expr.id, definition), - Err(true) => self.record_def(expr.id, err_path_resolution()), - Err(false) => { - debug!("(resolving expression) didn't find struct def",); - - resolve_error(self, - path.span, - ResolutionError::DoesNotNameAStruct( - &path_names_to_string(path, 0)) - ); - self.record_def(expr.id, err_path_resolution()); - } - } + self.resolve_struct_path(expr.id, path); visit::walk_expr(self, expr); } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 1c60ccb9765..73d0e5e50c6 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -166,6 +166,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { loc.file.name, loc.line); } + error!(" master span: {:?}: `{}`", path.span, self.span.snippet(path.span)); return vec!(); } @@ -1493,7 +1494,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> Def::StructCtor(..) | Def::VariantCtor(..) | Def::Const(..) | Def::AssociatedConst(..) | Def::Struct(..) | Def::Variant(..) | - Def::TyAlias(..) | Def::AssociatedTy(..) => { + Def::TyAlias(..) | Def::AssociatedTy(..) | + Def::SelfTy(..) => { paths_to_process.push((id, p.clone(), Some(ref_kind))) } def => error!("unexpected definition kind when processing collected paths: {:?}", diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs index 0378d75cc6e..eb613c3afda 100644 --- a/src/librustc_save_analysis/json_dumper.rs +++ b/src/librustc_save_analysis/json_dumper.rs @@ -129,7 +129,7 @@ impl From<DefId> for Id { #[derive(Debug, RustcEncodable)] struct Import { kind: ImportKind, - id: Id, + ref_id: Option<Id>, span: SpanData, name: String, value: String, @@ -146,7 +146,7 @@ impl From<ExternCrateData> for Import { fn from(data: ExternCrateData) -> Import { Import { kind: ImportKind::ExternCrate, - id: From::from(data.id), + ref_id: None, span: data.span, name: data.name, value: String::new(), @@ -157,7 +157,7 @@ impl From<UseData> for Import { fn from(data: UseData) -> Import { Import { kind: ImportKind::Use, - id: From::from(data.id), + ref_id: data.mod_id.map(|id| From::from(id)), span: data.span, name: data.name, value: String::new(), @@ -168,7 +168,7 @@ impl From<UseGlobData> for Import { fn from(data: UseGlobData) -> Import { Import { kind: ImportKind::GlobUse, - id: From::from(data.id), + ref_id: None, span: data.span, name: "*".to_owned(), value: data.names.join(", "), diff --git a/src/librustc_trans/assert_module_sources.rs b/src/librustc_trans/assert_module_sources.rs index 7fe6d2bbfe2..264ed4cd12f 100644 --- a/src/librustc_trans/assert_module_sources.rs +++ b/src/librustc_trans/assert_module_sources.rs @@ -134,7 +134,7 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> { /// Scan for a `cfg="foo"` attribute and check whether we have a /// cfg flag called `foo`. fn check_config(&self, attr: &ast::Attribute) -> bool { - let config = &self.tcx.map.krate().config; + let config = &self.tcx.sess.parse_sess.config; let value = self.field(attr, CFG); debug!("check_config(config={:?}, value={:?})", config, value); if config.iter().any(|c| c.check_name(&value[..])) { diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs index f0661e03bc8..bf2a5d76c10 100644 --- a/src/librustc_trans/back/symbol_names.rs +++ b/src/librustc_trans/back/symbol_names.rs @@ -99,7 +99,8 @@ use common::SharedCrateContext; use monomorphize::Instance; -use util::sha2::{Digest, Sha256}; +use rustc_data_structures::fmt_wrap::FmtWrap; +use rustc_data_structures::blake2b::Blake2bHasher; use rustc::middle::weak_lang_items; use rustc::hir::def_id::LOCAL_CRATE; @@ -113,21 +114,6 @@ use rustc::util::common::record_time; use syntax::attr; use syntax::parse::token::{self, InternedString}; -use serialize::hex::ToHex; - -use std::hash::Hasher; - -struct Sha256Hasher<'a>(&'a mut Sha256); - -impl<'a> Hasher for Sha256Hasher<'a> { - fn write(&mut self, msg: &[u8]) { - self.0.input(msg) - } - - fn finish(&self) -> u64 { - bug!("Sha256Hasher::finish should not be called"); - } -} fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, @@ -149,12 +135,9 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, let tcx = scx.tcx(); - let mut hash_state = scx.symbol_hasher().borrow_mut(); - record_time(&tcx.sess.perf_stats.symbol_hash_time, || { - hash_state.reset(); - let hasher = Sha256Hasher(&mut hash_state); - let mut hasher = ty::util::TypeIdHasher::new(tcx, hasher); + let mut hasher = ty::util::TypeIdHasher::new(tcx, Blake2bHasher::new(8, &[])); + record_time(&tcx.sess.perf_stats.symbol_hash_time, || { // the main symbol name is not necessarily unique; hash in the // compiler's internal def-path, guaranteeing each symbol has a // truly unique path @@ -175,8 +158,9 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, }); // 64 bits should be enough to avoid collisions. - let output = hash_state.result_bytes(); - format!("h{}", output[..8].to_hex()) + let mut hasher = hasher.into_inner(); + let hash_bytes = hasher.finalize(); + format!("h{:x}", FmtWrap(hash_bytes)) } impl<'a, 'tcx> Instance<'tcx> { diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index d4d4f883e7b..977ababbf56 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -35,6 +35,7 @@ use back::link; use back::linker::LinkerInfo; use llvm::{Linkage, ValueRef, Vector, get_param}; use llvm; +use rustc::hir::def::Def; use rustc::hir::def_id::DefId; use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem}; use rustc::ty::subst::Substs; @@ -44,7 +45,6 @@ use rustc::ty::adjustment::CustomCoerceUnsized; use rustc::dep_graph::{DepNode, WorkProduct}; use rustc::hir::map as hir_map; use rustc::util::common::time; -use rustc::mir::mir_map::MirMap; use session::config::{self, NoDebugInfo}; use rustc_incremental::IncrementalHashesMap; use session::Session; @@ -79,7 +79,6 @@ use type_::Type; use type_of; use value::Value; use Disr; -use util::sha2::Sha256; use util::nodemap::{NodeSet, FnvHashMap, FnvHashSet}; use arena::TypedArena; @@ -866,7 +865,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> { false }; - let mir = def_id.and_then(|id| ccx.get_mir(id)); + let mir = def_id.map(|id| ccx.tcx().item_mir(id)); let debug_context = if let (false, Some((instance, sig, abi)), &Some(ref mir)) = (no_debug, definition, &mir) { @@ -1278,8 +1277,7 @@ fn write_metadata(cx: &SharedCrateContext, let metadata = cstore.encode_metadata(cx.tcx(), cx.export_map(), cx.link_meta(), - reachable_ids, - cx.mir_map()); + reachable_ids); if kind == MetadataKind::Uncompressed { return metadata; } @@ -1527,7 +1525,6 @@ pub fn filter_reachable_ids(tcx: TyCtxt, reachable: NodeSet) -> NodeSet { } pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - mir_map: &MirMap<'tcx>, analysis: ty::CrateAnalysis, incremental_hashes_map: &IncrementalHashesMap) -> CrateTranslation { @@ -1551,9 +1548,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let link_meta = link::build_link_meta(incremental_hashes_map, name); let shared_ccx = SharedCrateContext::new(tcx, - &mir_map, export_map, - Sha256::new(), link_meta.clone(), reachable, check_overflow); @@ -1716,8 +1711,21 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // `reachable_symbols` list later on so it should be ok. for cnum in sess.cstore.crates() { let syms = sess.cstore.reachable_ids(cnum); - reachable_symbols.extend(syms.into_iter().filter(|did| { - sess.cstore.is_extern_item(shared_ccx.tcx(), *did) + reachable_symbols.extend(syms.into_iter().filter(|&def_id| { + let applicable = match sess.cstore.describe_def(def_id) { + Some(Def::Static(..)) => true, + Some(Def::Fn(_)) => { + shared_ccx.tcx().lookup_generics(def_id).types.is_empty() + } + _ => false + }; + + if applicable { + let attrs = shared_ccx.tcx().get_attrs(def_id); + attr::contains_extern_indicator(sess.diagnostic(), &attrs) + } else { + false + } }).map(|did| { symbol_for_def_id(did, &shared_ccx, &symbol_map) })); diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 8a7919d01f5..8348da9f7b7 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -198,15 +198,13 @@ use rustc::traits; use rustc::ty::subst::{Substs, Subst}; use rustc::ty::{self, TypeFoldable, TyCtxt}; use rustc::ty::adjustment::CustomCoerceUnsized; -use rustc::mir::repr as mir; +use rustc::mir::{self, Location}; use rustc::mir::visit as mir_visit; use rustc::mir::visit::Visitor as MirVisitor; -use rustc::mir::repr::Location; use rustc_const_eval as const_eval; use syntax::abi::Abi; -use errors; use syntax_pos::DUMMY_SP; use base::custom_coerce_unsize_info; use context::SharedCrateContext; @@ -347,8 +345,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>, // Scan the MIR in order to find function calls, closures, and // drop-glue - let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(def_id), - || format!("Could not find MIR for static: {:?}", def_id)); + let mir = scx.tcx().item_mir(def_id); let empty_substs = scx.empty_substs_for_def_id(def_id); let visitor = MirNeighborCollector { @@ -368,8 +365,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>, // Scan the MIR in order to find function calls, closures, and // drop-glue - let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(instance.def), - || format!("Could not find MIR for function: {}", instance)); + let mir = scx.tcx().item_mir(instance.def); let visitor = MirNeighborCollector { scx: scx, @@ -452,11 +448,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { match *rvalue { mir::Rvalue::Aggregate(mir::AggregateKind::Closure(def_id, ref substs), _) => { - let mir = errors::expect(self.scx.sess().diagnostic(), - self.scx.get_mir(def_id), - || { - format!("Could not find MIR for closure: {:?}", def_id) - }); + let mir = self.scx.tcx().item_mir(def_id); let concrete_substs = monomorphize::apply_param_substs(self.scx, self.param_substs, @@ -1249,8 +1241,7 @@ fn collect_const_item_neighbours<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, { // Scan the MIR in order to find function calls, closures, and // drop-glue - let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(def_id), - || format!("Could not find MIR for const: {:?}", def_id)); + let mir = scx.tcx().item_mir(def_id); let visitor = MirNeighborCollector { scx: scx, diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index e1223221262..464b261b08e 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -19,6 +19,7 @@ use llvm::{True, False, Bool, OperandBundleDef}; use rustc::hir::def::Def; use rustc::hir::def_id::DefId; use rustc::infer::TransNormalize; +use rustc::mir::Mir; use rustc::util::common::MemoizationMap; use middle::lang_items::LangItem; use rustc::ty::subst::Substs; @@ -32,7 +33,6 @@ use consts; use debuginfo::{self, DebugLoc}; use declare; use machine; -use mir::CachedMir; use monomorphize; use type_::Type; use value::Value; @@ -46,7 +46,7 @@ use arena::TypedArena; use libc::{c_uint, c_char}; use std::ops::Deref; use std::ffi::CString; -use std::cell::{Cell, RefCell}; +use std::cell::{Cell, RefCell, Ref}; use syntax::ast; use syntax::parse::token::InternedString; @@ -250,10 +250,8 @@ pub fn validate_substs(substs: &Substs) { // Function context. Every LLVM function we create will have one of // these. pub struct FunctionContext<'a, 'tcx: 'a> { - // The MIR for this function. At present, this is optional because - // we only have MIR available for things that are local to the - // crate. - pub mir: Option<CachedMir<'a, 'tcx>>, + // The MIR for this function. + pub mir: Option<Ref<'tcx, Mir<'tcx>>>, // The ValueRef returned from a call to llvm::LLVMAddFunction; the // address of the first instruction in the sequence of @@ -313,8 +311,8 @@ pub struct FunctionContext<'a, 'tcx: 'a> { } impl<'a, 'tcx> FunctionContext<'a, 'tcx> { - pub fn mir(&self) -> CachedMir<'a, 'tcx> { - self.mir.clone().expect("fcx.mir was empty") + pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> { + self.mir.as_ref().map(Ref::clone).expect("fcx.mir was empty") } pub fn cleanup(&self) { @@ -490,7 +488,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> { self.set_lpad_ref(lpad.map(|p| &*self.fcx().lpad_arena.alloc(p))) } - pub fn mir(&self) -> CachedMir<'blk, 'tcx> { + pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> { self.fcx.mir() } @@ -609,7 +607,7 @@ impl<'blk, 'tcx> BlockAndBuilder<'blk, 'tcx> { self.bcx.llbb } - pub fn mir(&self) -> CachedMir<'blk, 'tcx> { + pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> { self.bcx.mir() } diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 2a72d42296d..fc75b1018ec 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -15,15 +15,12 @@ use middle::cstore::LinkMeta; use rustc::hir::def::ExportMap; use rustc::hir::def_id::DefId; use rustc::traits; -use rustc::mir::mir_map::MirMap; -use rustc::mir::repr as mir; use base; use builder::Builder; use common::BuilderRef_res; use debuginfo; use declare; use glue::DropGlueKind; -use mir::CachedMir; use monomorphize::Instance; use partitioning::CodegenUnit; @@ -35,7 +32,6 @@ use session::config::NoDebugInfo; use session::Session; use session::config; use symbol_map::SymbolMap; -use util::sha2::Sha256; use util::nodemap::{NodeSet, DefIdMap, FnvHashMap, FnvHashSet}; use std::ffi::{CStr, CString}; @@ -72,12 +68,9 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> { export_map: ExportMap, reachable: NodeSet, link_meta: LinkMeta, - symbol_hasher: RefCell<Sha256>, tcx: TyCtxt<'a, 'tcx, 'tcx>, stats: Stats, check_overflow: bool, - mir_map: &'a MirMap<'tcx>, - mir_cache: RefCell<DepTrackingMap<MirCache<'tcx>>>, use_dll_storage_attrs: bool, @@ -184,19 +177,6 @@ impl<'tcx> DepTrackingMapConfig for TraitSelectionCache<'tcx> { } } -// Cache for mir loaded from metadata -struct MirCache<'tcx> { - data: PhantomData<&'tcx ()> -} - -impl<'tcx> DepTrackingMapConfig for MirCache<'tcx> { - type Key = DefId; - type Value = Rc<mir::Mir<'tcx>>; - fn to_dep_node(key: &DefId) -> DepNode<DefId> { - DepNode::Mir(*key) - } -} - // # Global Cache pub struct ProjectionCache<'gcx> { @@ -453,9 +433,7 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>, - mir_map: &'b MirMap<'tcx>, export_map: ExportMap, - symbol_hasher: Sha256, link_meta: LinkMeta, reachable: NodeSet, check_overflow: bool) @@ -515,10 +493,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { export_map: export_map, reachable: reachable, link_meta: link_meta, - symbol_hasher: RefCell::new(symbol_hasher), tcx: tcx, - mir_map: mir_map, - mir_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())), stats: Stats { n_glues_created: Cell::new(0), n_null_glues: Cell::new(0), @@ -582,23 +557,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { self.use_dll_storage_attrs } - pub fn get_mir(&self, def_id: DefId) -> Option<CachedMir<'b, 'tcx>> { - if def_id.is_local() { - self.mir_map.map.get(&def_id).map(CachedMir::Ref) - } else { - if let Some(mir) = self.mir_cache.borrow().get(&def_id).cloned() { - return Some(CachedMir::Owned(mir)); - } - - let mir = self.sess().cstore.maybe_get_item_mir(self.tcx, def_id); - let cached = mir.map(Rc::new); - if let Some(ref mir) = cached { - self.mir_cache.borrow_mut().insert(def_id, mir.clone()); - } - cached.map(CachedMir::Owned) - } - } - pub fn translation_items(&self) -> &RefCell<FnvHashSet<TransItem<'tcx>>> { &self.translation_items } @@ -613,14 +571,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { }) } - pub fn symbol_hasher(&self) -> &RefCell<Sha256> { - &self.symbol_hasher - } - - pub fn mir_map(&self) -> &MirMap<'tcx> { - &self.mir_map - } - pub fn metadata_symbol_name(&self) -> String { format!("rust_metadata_{}_{}", self.link_meta().crate_name, @@ -919,10 +869,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { &self.local().llsizingtypes } - pub fn symbol_hasher<'a>(&'a self) -> &'a RefCell<Sha256> { - &self.shared.symbol_hasher - } - pub fn type_hashcodes<'a>(&'a self) -> &'a RefCell<FnvHashMap<Ty<'tcx>, String>> { &self.local().type_hashcodes } @@ -1008,10 +954,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { self.shared.use_dll_storage_attrs() } - pub fn get_mir(&self, def_id: DefId) -> Option<CachedMir<'b, 'tcx>> { - self.shared.get_mir(def_id) - } - pub fn symbol_map(&self) -> &SymbolMap<'tcx> { &*self.local().symbol_map } diff --git a/src/librustc_trans/debuginfo/create_scope_map.rs b/src/librustc_trans/debuginfo/create_scope_map.rs index 1d7e4991aa8..e0c1a80be39 100644 --- a/src/librustc_trans/debuginfo/create_scope_map.rs +++ b/src/librustc_trans/debuginfo/create_scope_map.rs @@ -15,7 +15,7 @@ use super::utils::{DIB, span_start}; use llvm; use llvm::debuginfo::{DIScope, DISubprogram}; use common::{CrateContext, FunctionContext}; -use rustc::mir::repr::{Mir, VisibilityScope}; +use rustc::mir::{Mir, VisibilityScope}; use libc::c_uint; use std::ptr; @@ -45,7 +45,7 @@ impl MirDebugScope { /// Produce DIScope DIEs for each MIR Scope which has variables defined in it. /// If debuginfo is disabled, the returned vector is empty. pub fn create_mir_scopes(fcx: &FunctionContext) -> IndexVec<VisibilityScope, MirDebugScope> { - let mir = fcx.mir.clone().expect("create_mir_scopes: missing MIR for fn"); + let mir = fcx.mir(); let null_scope = MirDebugScope { scope_metadata: ptr::null_mut(), file_start_pos: BytePos(0), diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 2804e3ffe37..863aecc8244 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -30,7 +30,7 @@ use rustc::ty::fold::TypeVisitor; use rustc::ty::subst::Substs; use rustc::ty::util::TypeIdHasher; use rustc::hir; -use rustc_data_structures::blake2b; +use rustc_data_structures::blake2b::Blake2bHasher; use {type_of, machine, monomorphize}; use common::CrateContext; use type_::Type; @@ -149,10 +149,16 @@ impl<'tcx> TypeMap<'tcx> { None => { /* generate one */} }; + // The hasher we are using to generate the UniqueTypeId. We want + // something that provides more than the 64 bits of the DefaultHasher. + const TYPE_ID_HASH_LENGTH: usize = 20; + let mut type_id_hasher = TypeIdHasher::new(cx.tcx(), - DebugInfoTypeIdHasher::new()); + Blake2bHasher::new(TYPE_ID_HASH_LENGTH, &[])); type_id_hasher.visit_ty(type_); - let hash = type_id_hasher.into_inner().into_hash(); + let mut hash_state = type_id_hasher.into_inner(); + let hash: &[u8] = hash_state.finalize(); + debug_assert!(hash.len() == TYPE_ID_HASH_LENGTH); let mut unique_type_id = String::with_capacity(TYPE_ID_HASH_LENGTH * 2); @@ -164,39 +170,6 @@ impl<'tcx> TypeMap<'tcx> { self.type_to_unique_id.insert(type_, UniqueTypeId(key)); return UniqueTypeId(key); - - // The hasher we are using to generate the UniqueTypeId. We want - // something that provides more than the 64 bits of the DefaultHasher. - const TYPE_ID_HASH_LENGTH: usize = 20; - - struct DebugInfoTypeIdHasher { - state: blake2b::Blake2bCtx - } - - impl ::std::hash::Hasher for DebugInfoTypeIdHasher { - fn finish(&self) -> u64 { - unimplemented!() - } - - #[inline] - fn write(&mut self, bytes: &[u8]) { - blake2b::blake2b_update(&mut self.state, bytes); - } - } - - impl DebugInfoTypeIdHasher { - fn new() -> DebugInfoTypeIdHasher { - DebugInfoTypeIdHasher { - state: blake2b::blake2b_new(TYPE_ID_HASH_LENGTH, &[]) - } - } - - fn into_hash(self) -> [u8; TYPE_ID_HASH_LENGTH] { - let mut hash = [0u8; TYPE_ID_HASH_LENGTH]; - blake2b::blake2b_final(self.state, &mut hash); - hash - } - } } // Get the UniqueTypeId for an enum variant. Enum variants are not really diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 813915bfd6e..3bc5f4f3dbc 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -32,7 +32,7 @@ use abi::Abi; use common::{CrateContext, FunctionContext, Block, BlockAndBuilder}; use monomorphize::{self, Instance}; use rustc::ty::{self, Ty}; -use rustc::mir::repr as mir; +use rustc::mir; use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; use util::nodemap::{DefIdMap, FnvHashMap, FnvHashSet}; diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 81c0c184f66..07acc54962b 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -25,6 +25,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] +#![feature(cell_extras)] #![feature(const_fn)] #![feature(custom_attribute)] #![feature(dotdot_in_tuple_patterns)] diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index 455cf4eb455..a934da12b9e 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -13,9 +13,7 @@ use rustc_data_structures::bitvec::BitVector; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; -use rustc::mir::repr as mir; -use rustc::mir::repr::TerminatorKind; -use rustc::mir::repr::Location; +use rustc::mir::{self, Location, TerminatorKind}; use rustc::mir::visit::{Visitor, LvalueContext}; use rustc::mir::traversal; use common::{self, Block, BlockAndBuilder}; diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index d60dc3fe843..8bf27b4babf 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -12,7 +12,7 @@ use llvm::{self, ValueRef}; use rustc_const_eval::{ErrKind, ConstEvalErr, note_const_eval_err}; use rustc::middle::lang_items; use rustc::ty; -use rustc::mir::repr as mir; +use rustc::mir; use abi::{Abi, FnType, ArgType}; use adt; use base; @@ -37,13 +37,14 @@ use super::analyze::CleanupKind; use super::constant::Const; use super::lvalue::{LvalueRef}; use super::operand::OperandRef; -use super::operand::OperandValue::*; +use super::operand::OperandValue::{Pair, Ref, Immediate}; + +use std::cell::Ref as CellRef; impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { pub fn trans_block(&mut self, bb: mir::BasicBlock) { let mut bcx = self.bcx(bb); - let mir = self.mir.clone(); - let data = &mir[bb]; + let data = &CellRef::clone(&self.mir)[bb]; debug!("trans_block({:?}={:?})", bb, data); @@ -228,7 +229,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { } mir::TerminatorKind::Drop { ref location, target, unwind } => { - let ty = location.ty(&mir, bcx.tcx()).to_ty(bcx.tcx()); + let ty = location.ty(&self.mir, bcx.tcx()).to_ty(bcx.tcx()); let ty = bcx.monomorphize(&ty); // Double check for necessity to drop diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 3e7d8acf610..3d0d8897609 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -16,7 +16,7 @@ use rustc_const_math::ConstFloat::*; use rustc_const_math::{ConstInt, ConstIsize, ConstUsize, ConstMathErr}; use rustc::hir::def_id::DefId; use rustc::infer::TransNormalize; -use rustc::mir::repr as mir; +use rustc::mir; use rustc::mir::tcx::LvalueTy; use rustc::traits; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -261,9 +261,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { } } - let mir = ccx.get_mir(instance.def).unwrap_or_else(|| { - bug!("missing constant MIR for {}", instance) - }); + let mir = ccx.tcx().item_mir(instance.def); MirConstContext::new(ccx, &mir, instance.substs, args).trans() } diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs index 8e65eac2e80..d28c466e230 100644 --- a/src/librustc_trans/mir/lvalue.rs +++ b/src/librustc_trans/mir/lvalue.rs @@ -10,7 +10,7 @@ use llvm::ValueRef; use rustc::ty::{self, Ty, TypeFoldable}; -use rustc::mir::repr as mir; +use rustc::mir; use rustc::mir::tcx::LvalueTy; use rustc_data_structures::indexed_vec::Idx; use adt; diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index b0c7d26c47e..d2adf88c916 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -11,7 +11,7 @@ use libc::c_uint; use llvm::{self, ValueRef}; use rustc::ty; -use rustc::mir::repr as mir; +use rustc::mir; use rustc::mir::tcx::LvalueTy; use session::config::FullDebugInfo; use base; @@ -23,8 +23,7 @@ use type_of; use syntax_pos::{DUMMY_SP, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos}; use syntax::parse::token::keywords; -use std::ops::Deref; -use std::rc::Rc; +use std::cell::Ref; use std::iter; use basic_block::BasicBlock; @@ -39,25 +38,9 @@ use rustc::mir::traversal; use self::operand::{OperandRef, OperandValue}; -#[derive(Clone)] -pub enum CachedMir<'mir, 'tcx: 'mir> { - Ref(&'mir mir::Mir<'tcx>), - Owned(Rc<mir::Mir<'tcx>>) -} - -impl<'mir, 'tcx: 'mir> Deref for CachedMir<'mir, 'tcx> { - type Target = mir::Mir<'tcx>; - fn deref(&self) -> &mir::Mir<'tcx> { - match *self { - CachedMir::Ref(r) => r, - CachedMir::Owned(ref rc) => rc - } - } -} - /// Master context for translating MIR. pub struct MirContext<'bcx, 'tcx:'bcx> { - mir: CachedMir<'bcx, 'tcx>, + mir: Ref<'tcx, mir::Mir<'tcx>>, /// Function context fcx: &'bcx common::FunctionContext<'bcx, 'tcx>, @@ -223,7 +206,7 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) { let scopes = debuginfo::create_mir_scopes(fcx); let mut mircx = MirContext { - mir: mir.clone(), + mir: Ref::clone(&mir), fcx: fcx, llpersonalityslot: None, blocks: block_bcxs, diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs index c9d83a33752..62eda56e2e1 100644 --- a/src/librustc_trans/mir/operand.rs +++ b/src/librustc_trans/mir/operand.rs @@ -10,7 +10,7 @@ use llvm::ValueRef; use rustc::ty::Ty; -use rustc::mir::repr as mir; +use rustc::mir; use rustc_data_structures::indexed_vec::Idx; use base; diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index b6172fa2a90..f25877b1de1 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -12,7 +12,7 @@ use llvm::{self, ValueRef}; use rustc::ty::{self, Ty}; use rustc::ty::cast::{CastTy, IntTy}; use rustc::ty::layout::Layout; -use rustc::mir::repr as mir; +use rustc::mir; use asm; use base; diff --git a/src/librustc_trans/mir/statement.rs b/src/librustc_trans/mir/statement.rs index 3d6aad37ed5..296a0e8049e 100644 --- a/src/librustc_trans/mir/statement.rs +++ b/src/librustc_trans/mir/statement.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::mir::repr as mir; +use rustc::mir; use base; use common::{self, BlockAndBuilder}; diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs index ab2a3986433..270ce79620f 100644 --- a/src/librustc_trans/monomorphize.rs +++ b/src/librustc_trans/monomorphize.rs @@ -26,7 +26,7 @@ pub struct Instance<'tcx> { impl<'tcx> fmt::Display for Instance<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ppaux::parameterized(f, &self.substs, self.def, ppaux::Ns::Value, &[]) + ppaux::parameterized(f, &self.substs, self.def, &[]) } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index c137fca58af..8799050b1b9 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1484,7 +1484,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { def: Def, opt_self_ty: Option<Ty<'tcx>>, base_path_ref_id: ast::NodeId, - base_segments: &[hir::PathSegment]) + base_segments: &[hir::PathSegment], + permit_variants: bool) -> Ty<'tcx> { let tcx = self.tcx(); @@ -1515,6 +1516,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { did, base_segments.last().unwrap()) } + Def::Variant(did) if permit_variants => { + // Convert "variant type" as if it were a real type. + // The resulting `Ty` is type of the variant's enum for now. + tcx.prohibit_type_params(base_segments.split_last().unwrap().1); + self.ast_path_to_ty(rscope, + span, + param_mode, + tcx.parent_def_id(did).unwrap(), + base_segments.last().unwrap()) + } Def::TyParam(did) => { tcx.prohibit_type_params(base_segments); @@ -1604,7 +1615,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { opt_self_ty: Option<Ty<'tcx>>, base_path_ref_id: ast::NodeId, base_segments: &[hir::PathSegment], - assoc_segments: &[hir::PathSegment]) + assoc_segments: &[hir::PathSegment], + permit_variants: bool) -> (Ty<'tcx>, Def) { // Convert the base type. debug!("finish_resolving_def_to_ty(base_def={:?}, \ @@ -1619,7 +1631,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { base_def, opt_self_ty, base_path_ref_id, - base_segments); + base_segments, + permit_variants); debug!("finish_resolving_def_to_ty: base_def_to_ty returned {:?}", base_ty); // If any associated type segments remain, attempt to resolve them. @@ -1775,7 +1788,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { opt_self_ty, ast_ty.id, &path.segments[..base_ty_end], - &path.segments[base_ty_end..]); + &path.segments[base_ty_end..], + false); // Write back the new resolution. if path_res.depth != 0 { diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index d3fef0711b2..c842514227c 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -489,8 +489,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expected: Ty<'tcx>) -> Ty<'tcx> { // Resolve the path and check the definition for errors. - let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(path, pat.id, - pat.span) { + let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(path, pat.id) { variant_ty } else { for field in fields { diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 5be77cb12e9..ccc944813ff 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -196,6 +196,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { // Function items are coercible to any closure // type; function pointers are not (that would // require double indirection). + // Additionally, we permit coercion of function + // items to drop the unsafe qualifier. self.coerce_from_fn_item(a, a_f, b) } ty::TyFnPtr(a_f) => { @@ -504,6 +506,24 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { Ok((target, AdjustDerefRef(adjustment))) } + fn coerce_from_safe_fn(&self, + a: Ty<'tcx>, + fn_ty_a: &'tcx ty::BareFnTy<'tcx>, + b: Ty<'tcx>) + -> CoerceResult<'tcx> { + if let ty::TyFnPtr(fn_ty_b) = b.sty { + match (fn_ty_a.unsafety, fn_ty_b.unsafety) { + (hir::Unsafety::Normal, hir::Unsafety::Unsafe) => { + let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a); + return self.unify_and_identity(unsafe_a, b) + .map(|(ty, _)| (ty, AdjustUnsafeFnPointer)); + } + _ => {} + } + } + self.unify_and_identity(a, b) + } + fn coerce_from_fn_pointer(&self, a: Ty<'tcx>, fn_ty_a: &'tcx ty::BareFnTy<'tcx>, @@ -516,17 +536,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { let b = self.shallow_resolve(b); debug!("coerce_from_fn_pointer(a={:?}, b={:?})", a, b); - if let ty::TyFnPtr(fn_ty_b) = b.sty { - match (fn_ty_a.unsafety, fn_ty_b.unsafety) { - (hir::Unsafety::Normal, hir::Unsafety::Unsafe) => { - let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a); - return self.unify_and_identity(unsafe_a, b) - .map(|(ty, _)| (ty, AdjustUnsafeFnPointer)); - } - _ => {} - } - } - self.unify_and_identity(a, b) + self.coerce_from_safe_fn(a, fn_ty_a, b) } fn coerce_from_fn_item(&self, @@ -544,7 +554,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { match b.sty { ty::TyFnPtr(_) => { let a_fn_pointer = self.tcx.mk_fn_ptr(fn_ty_a); - self.unify_and_identity(a_fn_pointer, b).map(|(ty, _)| (ty, AdjustReifyFnPointer)) + self.coerce_from_safe_fn(a_fn_pointer, fn_ty_a, b) + .map(|(ty, _)| (ty, AdjustReifyFnPointer)) } _ => self.unify_and_identity(a, b), } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 21da8cd388c..75a14bb3db9 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1686,41 +1686,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { cause) } - /// Instantiates the type in `did` with the generics in `path` and returns - /// it (registering the necessary trait obligations along the way). - /// - /// Note that this function is only intended to be used with type-paths, - /// not with value-paths. - pub fn instantiate_type_path(&self, - did: DefId, - path: &hir::Path, - node_id: ast::NodeId) - -> Ty<'tcx> { - debug!("instantiate_type_path(did={:?}, path={:?})", did, path); - let mut ty = self.tcx.lookup_item_type(did).ty; - if ty.is_fn() { - // Tuple variants have fn type even in type namespace, extract true variant type from it - ty = self.tcx.no_late_bound_regions(&ty.fn_ret()).unwrap(); - } - let type_predicates = self.tcx.lookup_predicates(did); - let substs = AstConv::ast_path_substs_for_ty(self, self, - path.span, - PathParamMode::Optional, - did, - path.segments.last().unwrap()); - debug!("instantiate_type_path: ty={:?} substs={:?}", ty, substs); - let bounds = self.instantiate_bounds(path.span, substs, &type_predicates); - let cause = traits::ObligationCause::new(path.span, self.body_id, - traits::ItemObligation(did)); - self.add_obligations_for_parameters(cause, &bounds); - - let ty_substituted = self.instantiate_type_scheme(path.span, substs, &ty); - self.write_substs(node_id, ty::ItemSubsts { - substs: substs - }); - ty_substituted - } - pub fn write_nil(&self, node_id: ast::NodeId) { self.write_ty(node_id, self.tcx.mk_nil()); } @@ -3251,47 +3216,55 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } pub fn check_struct_path(&self, - path: &hir::Path, - node_id: ast::NodeId, - span: Span) - -> Option<(ty::VariantDef<'tcx>, Ty<'tcx>)> { - let def = self.finish_resolving_struct_path(path, node_id, span); + path: &hir::Path, + node_id: ast::NodeId) + -> Option<(ty::VariantDef<'tcx>, Ty<'tcx>)> { + let (def, ty) = self.finish_resolving_struct_path(path, node_id); let variant = match def { Def::Err => { self.set_tainted_by_errors(); return None; } - Def::Variant(did) => { - let type_did = self.tcx.parent_def_id(did).unwrap(); - Some((type_did, self.tcx.expect_variant_def(def))) - } - Def::Struct(type_did) | Def::Union(type_did) => { - Some((type_did, self.tcx.expect_variant_def(def))) + Def::Variant(..) => { + match ty.sty { + ty::TyAdt(adt, substs) => { + Some((adt.variant_of_def(def), adt.did, substs)) + } + _ => bug!("unexpected type: {:?}", ty.sty) + } } - Def::TyAlias(did) | Def::AssociatedTy(did) => { - match self.tcx.opt_lookup_item_type(did).map(|scheme| &scheme.ty.sty) { - Some(&ty::TyAdt(adt, _)) if !adt.is_enum() => { - Some((did, adt.struct_variant())) + Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) | + Def::AssociatedTy(..) | Def::SelfTy(..) => { + match ty.sty { + ty::TyAdt(adt, substs) if !adt.is_enum() => { + Some((adt.struct_variant(), adt.did, substs)) } _ => None, } } - _ => None + _ => bug!("unexpected definition: {:?}", def) }; - if let Some((def_id, variant)) = variant { + if let Some((variant, did, substs)) = variant { if variant.ctor_kind == CtorKind::Fn && !self.tcx.sess.features.borrow().relaxed_adts { emit_feature_err(&self.tcx.sess.parse_sess, - "relaxed_adts", span, GateIssue::Language, + "relaxed_adts", path.span, GateIssue::Language, "tuple structs and variants in struct patterns are unstable"); } - let ty = self.instantiate_type_path(def_id, path, node_id); + + // Check bounds on type arguments used in the path. + let type_predicates = self.tcx.lookup_predicates(did); + let bounds = self.instantiate_bounds(path.span, substs, &type_predicates); + let cause = traits::ObligationCause::new(path.span, self.body_id, + traits::ItemObligation(did)); + self.add_obligations_for_parameters(cause, &bounds); + Some((variant, ty)) } else { struct_span_err!(self.tcx.sess, path.span, E0071, - "`{}` does not name a struct or a struct variant", - pprust::path_to_string(path)) + "expected struct, variant or union type, found {}", + ty.sort_string(self.tcx)) .span_label(path.span, &format!("not a struct")) .emit(); None @@ -3305,12 +3278,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx> { // Find the relevant variant - let (variant, struct_ty) = if let Some(variant_ty) = self.check_struct_path(path, expr.id, - expr.span) { + let (variant, struct_ty) = if let Some(variant_ty) = self.check_struct_path(path, expr.id) { variant_ty } else { self.check_struct_fields_on_error(fields, base_expr); - return self.tcx().types.err; + return self.tcx.types.err; }; self.check_expr_struct_fields(struct_ty, path.span, variant, fields, @@ -3805,7 +3777,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } err.emit(); - self.tcx().types.err + self.tcx.types.err } } } @@ -3815,29 +3787,26 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary. // The newly resolved definition is written into `def_map`. - pub fn finish_resolving_struct_path(&self, - path: &hir::Path, - node_id: ast::NodeId, - span: Span) - -> Def + fn finish_resolving_struct_path(&self, + path: &hir::Path, + node_id: ast::NodeId) + -> (Def, Ty<'tcx>) { - let path_res = self.tcx().expect_resolution(node_id); - if path_res.depth == 0 { - // If fully resolved already, we don't have to do anything. - path_res.base_def - } else { - let base_ty_end = path.segments.len() - path_res.depth; - let (_ty, def) = AstConv::finish_resolving_def_to_ty(self, self, span, - PathParamMode::Optional, - path_res.base_def, - None, - node_id, - &path.segments[..base_ty_end], - &path.segments[base_ty_end..]); - // Write back the new resolution. - self.tcx().def_map.borrow_mut().insert(node_id, PathResolution::new(def)); - def + let path_res = self.tcx.expect_resolution(node_id); + let base_ty_end = path.segments.len() - path_res.depth; + let (ty, def) = AstConv::finish_resolving_def_to_ty(self, self, path.span, + PathParamMode::Optional, + path_res.base_def, + None, + node_id, + &path.segments[..base_ty_end], + &path.segments[base_ty_end..], + true); + // Write back the new resolution. + if path_res.depth != 0 { + self.tcx.def_map.borrow_mut().insert(node_id, PathResolution::new(def)); } + (def, ty) } // Resolve associated value path into a base type and associated constant or method definition. @@ -3849,7 +3818,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span: Span) -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment]) { - let path_res = self.tcx().expect_resolution(node_id); + let path_res = self.tcx.expect_resolution(node_id); if path_res.depth == 0 { // If fully resolved already, we don't have to do anything. (path_res.base_def, opt_self_ty, &path.segments) @@ -3863,7 +3832,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { opt_self_ty, node_id, &ty_segments[..base_ty_end], - &ty_segments[base_ty_end..]); + &ty_segments[base_ty_end..], + false); // Resolve an associated constant or method on the previously resolved type. let item_segment = path.segments.last().unwrap(); @@ -3883,7 +3853,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; // Write back the new resolution. - self.tcx().def_map.borrow_mut().insert(node_id, PathResolution::new(def)); + self.tcx.def_map.borrow_mut().insert(node_id, PathResolution::new(def)); (def, Some(ty), slice::ref_slice(item_segment)) } } @@ -4308,7 +4278,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // the referenced item. let ty_substituted = self.instantiate_type_scheme(span, &substs, &scheme.ty); - if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated { // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method` // is inherent, there is no `Self` parameter, instead, the impl needs diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 189f8490f6c..7dd850180d4 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -895,17 +895,14 @@ fn some_func(x: &mut i32) { E0071: r##" You tried to use structure-literal syntax to create an item that is -not a struct-style structure or enum variant. +not a structure or enum variant. Example of erroneous code: ```compile_fail,E0071 -enum Foo { FirstValue(i32) }; - -let u = Foo::FirstValue { value: 0 }; // error: Foo::FirstValue - // isn't a structure! -// or even simpler, if the name doesn't refer to a structure at all. -let t = u32 { value: 4 }; // error: `u32` does not name a structure. +type U32 = u32; +let t = U32 { value: 4 }; // error: expected struct, variant or union type, + // found builtin type `u32` ``` To fix this, ensure that the name was correctly spelled, and that diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 208819a4a0b..5ce75810006 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -163,14 +163,16 @@ pub fn run_core(search_paths: SearchPaths, let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); let cstore = Rc::new(CStore::new(&dep_graph)); - let sess = session::build_session_(sessopts, &dep_graph, cpath, diagnostic_handler, - codemap, cstore.clone()); + let mut sess = session::build_session_( + sessopts, &dep_graph, cpath, diagnostic_handler, codemap, cstore.clone() + ); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let mut cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs)); target_features::add_configuration(&mut cfg, &sess); + sess.parse_sess.config = cfg; - let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input)); + let krate = panictry!(driver::phase_1_parse_input(&sess, &input)); let name = link::find_crate_name(Some(&sess), &krate.attrs, &input); @@ -189,7 +191,7 @@ pub fn run_core(search_paths: SearchPaths, resolutions, &arenas, &name, - |tcx, _, analysis, _, result| { + |tcx, analysis, _, result| { if let Err(_) = result { sess.fatal("Compilation failed, aborting rustdoc"); } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index d1d2b14806f..45c3d413500 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -73,24 +73,20 @@ pub fn run(input: &str, }; let codemap = Rc::new(CodeMap::new()); - let diagnostic_handler = errors::Handler::with_tty_emitter(ColorConfig::Auto, - true, - false, - Some(codemap.clone())); + let handler = + errors::Handler::with_tty_emitter(ColorConfig::Auto, true, false, Some(codemap.clone())); let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); let cstore = Rc::new(CStore::new(&dep_graph)); - let sess = session::build_session_(sessopts, - &dep_graph, - Some(input_path.clone()), - diagnostic_handler, - codemap, - cstore.clone()); + let mut sess = session::build_session_( + sessopts, &dep_graph, Some(input_path.clone()), handler, codemap, cstore.clone(), + ); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); + sess.parse_sess.config = + config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone())); - let cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone())); - let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input)); + let krate = panictry!(driver::phase_1_parse_input(&sess, &input)); let driver::ExpansionResult { defs, mut hir_forest, .. } = { phase_2_configure_and_expand( &sess, &cstore, krate, None, "rustdoc-test", None, MakeGlobMap::No, |_| Ok(()) @@ -236,18 +232,16 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths, let dep_graph = DepGraph::new(false); let cstore = Rc::new(CStore::new(&dep_graph)); - let sess = session::build_session_(sessopts, - &dep_graph, - None, - diagnostic_handler, - codemap, - cstore.clone()); + let mut sess = session::build_session_( + sessopts, &dep_graph, None, diagnostic_handler, codemap, cstore.clone(), + ); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let outdir = Mutex::new(TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir")); let libdir = sess.target_filesearch(PathKind::All).get_lib_path(); let mut control = driver::CompileController::basic(); - let cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone())); + sess.parse_sess.config = + config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone())); let out = Some(outdir.lock().unwrap().path().to_path_buf()); if no_run { @@ -255,9 +249,7 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths, } let res = panic::catch_unwind(AssertUnwindSafe(|| { - driver::compile_input(&sess, &cstore, cfg.clone(), - &input, &out, - &None, None, &control) + driver::compile_input(&sess, &cstore, &input, &out, &None, None, &control) })); match res { diff --git a/src/libstd/build.rs b/src/libstd/build.rs index c811ed3bded..72cd6e4830b 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -58,6 +58,8 @@ fn main() { println!("cargo:rustc-link-lib=ws2_32"); println!("cargo:rustc-link-lib=userenv"); println!("cargo:rustc-link-lib=shell32"); + } else if target.contains("fuchsia") { + println!("cargo:rustc-link-lib=magenta"); } } diff --git a/src/libstd/io/impls.rs b/src/libstd/io/impls.rs index cd05e6b5de9..6b26c016638 100644 --- a/src/libstd/io/impls.rs +++ b/src/libstd/io/impls.rs @@ -147,6 +147,10 @@ impl<B: BufRead + ?Sized> BufRead for Box<B> { // ============================================================================= // In-memory buffer implementations +/// Read is implemented for `&[u8]` by copying from the slice. +/// +/// Note that reading updates the slice to point to the yet unread part. +/// The slice will be empty when EOF is reached. #[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for &'a [u8] { #[inline] @@ -180,6 +184,11 @@ impl<'a> BufRead for &'a [u8] { fn consume(&mut self, amt: usize) { *self = &self[amt..]; } } +/// Write is implemented for `&mut [u8]` by copying into the slice, overwriting +/// its data. +/// +/// Note that writing updates the slice to point to the yet unwritten part. +/// The slice will be empty when it has been completely overwritten. #[stable(feature = "rust1", since = "1.0.0")] impl<'a> Write for &'a mut [u8] { #[inline] @@ -204,6 +213,8 @@ impl<'a> Write for &'a mut [u8] { fn flush(&mut self) -> io::Result<()> { Ok(()) } } +/// Write is implemented for `Vec<u8>` by appending to the vector. +/// The vector will grow as needed. #[stable(feature = "rust1", since = "1.0.0")] impl Write for Vec<u8> { #[inline] diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index d801fa028cc..0ce6b0a9431 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -286,7 +286,7 @@ pub mod builtin { /// // fn concat_idents!(new, fun, name) { } // not usable in this way! /// # } /// ``` - #[unstable(feature = "concat_idents", issue = "29599")] + #[unstable(feature = "concat_idents_macro", issue = "29599")] #[macro_export] macro_rules! concat_idents { ($($e:ident),*) => ({ /* compiler built-in */ }) diff --git a/src/libstd/os/raw.rs b/src/libstd/os/raw.rs index 6c5c1b90a4a..2a918d8aeb7 100644 --- a/src/libstd/os/raw.rs +++ b/src/libstd/os/raw.rs @@ -18,7 +18,8 @@ target_arch = "arm", target_arch = "powerpc", target_arch = "powerpc64", - target_arch = "s390x"))))] + target_arch = "s390x")), + all(target_os = "fuchsia", target_arch = "aarch64")))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8; #[cfg(not(any(target_os = "android", target_os = "emscripten", @@ -26,7 +27,8 @@ target_arch = "arm", target_arch = "powerpc", target_arch = "powerpc64", - target_arch = "s390x")))))] + target_arch = "s390x")), + all(target_os = "fuchsia", target_arch = "aarch64"))))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8; #[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8; #[stable(feature = "raw_os", since = "1.1.0")] pub type c_uchar = u8; diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs index f28a6ad3375..3aebb8c18ec 100644 --- a/src/libstd/sys/unix/rand.rs +++ b/src/libstd/sys/unix/rand.rs @@ -27,7 +27,8 @@ fn next_u64(mut fill_buf: &mut FnMut(&mut [u8])) -> u64 { #[cfg(all(unix, not(target_os = "ios"), not(target_os = "openbsd"), - not(target_os = "freebsd")))] + not(target_os = "freebsd"), + not(target_os = "fuchsia")))] mod imp { use self::OsRngInner::*; use super::{next_u32, next_u64}; @@ -339,3 +340,54 @@ mod imp { } } } + +#[cfg(target_os = "fuchsia")] +mod imp { + use super::{next_u32, next_u64}; + + use io; + use rand::Rng; + + #[link(name = "magenta")] + extern { + fn mx_cprng_draw(buffer: *mut u8, len: usize) -> isize; + } + + fn getrandom(buf: &mut [u8]) -> isize { + unsafe { mx_cprng_draw(buf.as_mut_ptr(), buf.len()) } + } + + pub struct OsRng { + // dummy field to ensure that this struct cannot be constructed outside + // of this module + _dummy: (), + } + + impl OsRng { + /// Create a new `OsRng`. + pub fn new() -> io::Result<OsRng> { + Ok(OsRng { _dummy: () }) + } + } + + impl Rng for OsRng { + fn next_u32(&mut self) -> u32 { + next_u32(&mut |v| self.fill_bytes(v)) + } + fn next_u64(&mut self) -> u64 { + next_u64(&mut |v| self.fill_bytes(v)) + } + fn fill_bytes(&mut self, v: &mut [u8]) { + let mut buf = v; + while !buf.is_empty() { + let ret = getrandom(buf); + if ret < 0 { + panic!("kernel mx_cprng_draw call failed! (returned {}, buf.len() {})", + ret, buf.len()); + } + let move_buf = buf; + buf = &mut move_buf[(ret as usize)..]; + } + } + } +} diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 37e306de325..8864694c932 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -477,7 +477,6 @@ pub type CrateConfig = Vec<P<MetaItem>>; pub struct Crate { pub module: Mod, pub attrs: Vec<Attribute>, - pub config: CrateConfig, pub span: Span, pub exported_macros: Vec<MacroDef>, } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index dc02c26039c..0335f210347 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -501,10 +501,7 @@ pub fn requests_inline(attrs: &[Attribute]) -> bool { } /// Tests if a cfg-pattern matches the cfg set -pub fn cfg_matches(cfgs: &[P<MetaItem>], cfg: &ast::MetaItem, - sess: &ParseSess, - features: Option<&Features>) - -> bool { +pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) -> bool { match cfg.node { ast::MetaItemKind::List(ref pred, ref mis) => { for mi in mis.iter() { @@ -518,10 +515,10 @@ pub fn cfg_matches(cfgs: &[P<MetaItem>], cfg: &ast::MetaItem, // that they won't fail with the loop above. match &pred[..] { "any" => mis.iter().any(|mi| { - cfg_matches(cfgs, mi.meta_item().unwrap(), sess, features) + cfg_matches(mi.meta_item().unwrap(), sess, features) }), "all" => mis.iter().all(|mi| { - cfg_matches(cfgs, mi.meta_item().unwrap(), sess, features) + cfg_matches(mi.meta_item().unwrap(), sess, features) }), "not" => { if mis.len() != 1 { @@ -529,7 +526,7 @@ pub fn cfg_matches(cfgs: &[P<MetaItem>], cfg: &ast::MetaItem, return false; } - !cfg_matches(cfgs, mis[0].meta_item().unwrap(), sess, features) + !cfg_matches(mis[0].meta_item().unwrap(), sess, features) }, p => { span_err!(sess.span_diagnostic, cfg.span, E0537, "invalid predicate `{}`", p); @@ -541,7 +538,7 @@ pub fn cfg_matches(cfgs: &[P<MetaItem>], cfg: &ast::MetaItem, if let (Some(feats), Some(gated_cfg)) = (features, GatedCfg::gate(cfg)) { gated_cfg.check_and_emit(sess, feats); } - contains(cfgs, cfg) + contains(&sess.config, cfg) } } } diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 01f81e5e2de..946257a16d5 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -20,7 +20,6 @@ use util::small_vector::SmallVector; /// A folder that strips out items that do not belong in the current configuration. pub struct StripUnconfigured<'a> { - pub config: &'a ast::CrateConfig, pub should_test: bool, pub sess: &'a ParseSess, pub features: Option<&'a Features>, @@ -32,7 +31,6 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool) let features; { let mut strip_unconfigured = StripUnconfigured { - config: &krate.config.clone(), should_test: should_test, sess: sess, features: None, @@ -107,7 +105,7 @@ impl<'a> StripUnconfigured<'a> { use attr::cfg_matches; match (cfg.meta_item(), mi.meta_item()) { (Some(cfg), Some(mi)) => - if cfg_matches(self.config, &cfg, self.sess, self.features) { + if cfg_matches(&cfg, self.sess, self.features) { self.process_cfg_attr(respan(mi.span, ast::Attribute_ { id: attr::mk_attr_id(), style: attr.node.style, @@ -148,7 +146,7 @@ impl<'a> StripUnconfigured<'a> { return true; } - attr::cfg_matches(self.config, mis[0].meta_item().unwrap(), self.sess, self.features) + attr::cfg_matches(mis[0].meta_item().unwrap(), self.sess, self.features) }) } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index c404c6d1162..cc097ab0efa 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -574,7 +574,6 @@ pub struct ExpansionData { /// -> expn_info of their expansion context stored into their span. pub struct ExtCtxt<'a> { pub parse_sess: &'a parse::ParseSess, - pub cfg: ast::CrateConfig, pub ecfg: expand::ExpansionConfig<'a>, pub crate_root: Option<&'static str>, pub resolver: &'a mut Resolver, @@ -583,13 +582,12 @@ pub struct ExtCtxt<'a> { } impl<'a> ExtCtxt<'a> { - pub fn new(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig, + pub fn new(parse_sess: &'a parse::ParseSess, ecfg: expand::ExpansionConfig<'a>, resolver: &'a mut Resolver) -> ExtCtxt<'a> { ExtCtxt { parse_sess: parse_sess, - cfg: cfg, ecfg: ecfg, crate_root: None, resolver: resolver, @@ -617,11 +615,11 @@ impl<'a> ExtCtxt<'a> { pub fn new_parser_from_tts(&self, tts: &[tokenstream::TokenTree]) -> parser::Parser<'a> { - parse::tts_to_parser(self.parse_sess, tts.to_vec(), self.cfg().clone()) + parse::tts_to_parser(self.parse_sess, tts.to_vec()) } pub fn codemap(&self) -> &'a CodeMap { self.parse_sess.codemap() } pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess } - pub fn cfg(&self) -> &ast::CrateConfig { &self.cfg } + pub fn cfg(&self) -> &ast::CrateConfig { &self.parse_sess.config } pub fn call_site(&self) -> Span { self.codemap().with_expn_info(self.backtrace(), |ei| match ei { Some(expn_info) => expn_info.call_site, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index e84a9208029..e3b23e239f9 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -293,11 +293,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } fn collect_invocations(&mut self, expansion: Expansion) -> (Expansion, Vec<Invocation>) { - let crate_config = mem::replace(&mut self.cx.cfg, Vec::new()); let result = { let mut collector = InvocationCollector { cfg: StripUnconfigured { - config: &crate_config, should_test: self.cx.ecfg.should_test, sess: self.cx.parse_sess, features: self.cx.ecfg.features, @@ -308,7 +306,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; (expansion.fold_with(&mut collector), collector.invocations) }; - self.cx.cfg = crate_config; if self.monotonic { let err_count = self.cx.parse_sess.span_diagnostic.err_count(); @@ -646,7 +643,7 @@ fn string_to_tts(text: String, parse_sess: &ParseSess) -> Vec<TokenTree> { .new_filemap(String::from("<macro expansion>"), None, text); let lexer = lexer::StringReader::new(&parse_sess.span_diagnostic, filemap); - let mut parser = Parser::new(parse_sess, Vec::new(), Box::new(lexer)); + let mut parser = Parser::new(parse_sess, Box::new(lexer)); panictry!(parser.parse_all_token_trees()) } diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 7f002d28166..f3497c130bf 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -331,7 +331,6 @@ pub mod rt { panictry!(parse::parse_item_from_source_str( "<quote expansion>".to_string(), s, - self.cfg().clone(), self.parse_sess())).expect("parse error") } @@ -339,7 +338,6 @@ pub mod rt { panictry!(parse::parse_stmt_from_source_str( "<quote expansion>".to_string(), s, - self.cfg().clone(), self.parse_sess())).expect("parse error") } @@ -347,7 +345,6 @@ pub mod rt { panictry!(parse::parse_expr_from_source_str( "<quote expansion>".to_string(), s, - self.cfg().clone(), self.parse_sess())) } @@ -355,7 +352,6 @@ pub mod rt { panictry!(parse::parse_tts_from_source_str( "<quote expansion>".to_string(), s, - self.cfg().clone(), self.parse_sess())) } } @@ -920,14 +916,6 @@ fn expand_parse_call(cx: &ExtCtxt, tts: &[TokenTree]) -> P<ast::Expr> { let (cx_expr, tts_expr) = expand_tts(cx, sp, tts); - let cfg_call = || cx.expr_method_call( - sp, cx.expr_ident(sp, id_ext("ext_cx")), - id_ext("cfg"), Vec::new()); - - let cfg_clone_call = || cx.expr_method_call( - sp, cfg_call(), - id_ext("clone"), Vec::new()); - let parse_sess_call = || cx.expr_method_call( sp, cx.expr_ident(sp, id_ext("ext_cx")), id_ext("parse_sess"), Vec::new()); @@ -935,7 +923,7 @@ fn expand_parse_call(cx: &ExtCtxt, let new_parser_call = cx.expr_call(sp, cx.expr_ident(sp, id_ext("new_parser_from_tts")), - vec!(parse_sess_call(), cfg_clone_call(), tts_expr)); + vec!(parse_sess_call(), tts_expr)); let path = vec![id_ext("syntax"), id_ext("ext"), id_ext("quote"), id_ext(parse_method)]; let mut args = vec![cx.expr_mut_addr_of(sp, new_parser_call)]; diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 30dc1823b37..ec48cae3f76 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -92,15 +92,8 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::T None => return DummyResult::expr(sp), }; // The file will be added to the code map by the parser - let p = - parse::new_sub_parser_from_file(cx.parse_sess(), - cx.cfg().clone(), - &res_rel_file(cx, - sp, - Path::new(&file)), - true, - None, - sp); + let path = res_rel_file(cx, sp, Path::new(&file)); + let p = parse::new_sub_parser_from_file(cx.parse_sess(), &path, true, None, sp); struct ExpandResult<'a> { p: parse::parser::Parser<'a>, diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 74def68b185..7e3fe328569 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -78,7 +78,6 @@ pub use self::NamedMatch::*; pub use self::ParseResult::*; use self::TokenTreeOrTokenTreeVec::*; -use ast; use ast::Ident; use syntax_pos::{self, BytePos, mk_sp, Span}; use codemap::Spanned; @@ -92,6 +91,7 @@ use parse::token; use print::pprust; use ptr::P; use tokenstream::{self, TokenTree}; +use util::small_vector::SmallVector; use std::mem; use std::rc::Rc; @@ -104,7 +104,7 @@ use std::collections::hash_map::Entry::{Vacant, Occupied}; #[derive(Clone)] enum TokenTreeOrTokenTreeVec { Tt(tokenstream::TokenTree), - TtSeq(Rc<Vec<tokenstream::TokenTree>>), + TtSeq(Vec<tokenstream::TokenTree>), } impl TokenTreeOrTokenTreeVec { @@ -161,7 +161,7 @@ pub fn count_names(ms: &[TokenTree]) -> usize { }) } -pub fn initial_matcher_pos(ms: Rc<Vec<TokenTree>>, sep: Option<Token>, lo: BytePos) +pub fn initial_matcher_pos(ms: Vec<TokenTree>, sep: Option<Token>, lo: BytePos) -> Box<MatcherPos> { let match_idx_hi = count_names(&ms[..]); let matches: Vec<_> = (0..match_idx_hi).map(|_| Vec::new()).collect(); @@ -279,17 +279,10 @@ pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool { } } -pub fn parse(sess: &ParseSess, - cfg: &ast::CrateConfig, - mut rdr: TtReader, - ms: &[TokenTree]) - -> NamedParseResult { - let mut cur_eis = Vec::new(); - cur_eis.push(initial_matcher_pos(Rc::new(ms.iter() - .cloned() - .collect()), - None, - rdr.peek().sp.lo)); +pub fn parse(sess: &ParseSess, mut rdr: TtReader, ms: &[TokenTree]) -> NamedParseResult { + let mut cur_eis = SmallVector::one(initial_matcher_pos(ms.to_owned(), + None, + rdr.peek().sp.lo)); loop { let mut bb_eis = Vec::new(); // black-box parsed by parser.rs @@ -484,7 +477,7 @@ pub fn parse(sess: &ParseSess, rdr.next_token(); } else /* bb_eis.len() == 1 */ { rdr.next_tok = { - let mut rust_parser = Parser::new(sess, cfg.clone(), Box::new(&mut rdr)); + let mut rust_parser = Parser::new(sess, Box::new(&mut rdr)); let mut ei = bb_eis.pop().unwrap(); if let TokenTree::Token(span, MatchNt(_, ident)) = ei.top_elts.get_tt(ei.idx) { let match_cur = ei.match_cur; diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index ceca698f479..431e757368c 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -115,7 +115,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, // rhs has holes ( `$id` and `$(...)` that need filled) let trncbr = new_tt_reader(&cx.parse_sess.span_diagnostic, Some(named_matches), rhs); - let mut p = Parser::new(cx.parse_sess(), cx.cfg().clone(), Box::new(trncbr)); + let mut p = Parser::new(cx.parse_sess(), Box::new(trncbr)); p.directory = cx.current_expansion.module.directory.clone(); p.restrictions = match cx.current_expansion.no_noninline_mod { true => Restrictions::NO_NONINLINE_MOD, @@ -220,7 +220,7 @@ pub fn compile(sess: &ParseSess, def: &ast::MacroDef) -> SyntaxExtension { // Parse the macro_rules! invocation (`none` is for no interpolations): let arg_reader = new_tt_reader(&sess.span_diagnostic, None, def.body.clone()); - let argument_map = match parse(sess, &Vec::new(), arg_reader, &argument_gram) { + let argument_map = match parse(sess, arg_reader, &argument_gram) { Success(m) => m, Failure(sp, tok) => { let s = parse_failure_msg(tok); diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 38a926b6e87..8a6a8e53a3e 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -10,14 +10,15 @@ use self::LockstepIterSize::*; use ast::Ident; -use syntax_pos::{Span, DUMMY_SP}; use errors::{Handler, DiagnosticBuilder}; use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal}; use parse::token::{DocComment, MatchNt, SubstNt}; use parse::token::{Token, Interpolated, NtIdent, NtTT}; use parse::token; use parse::lexer::TokenAndSpan; +use syntax_pos::{Span, DUMMY_SP}; use tokenstream::{self, TokenTree}; +use util::small_vector::SmallVector; use std::rc::Rc; use std::ops::Add; @@ -36,7 +37,7 @@ struct TtFrame { pub struct TtReader<'a> { pub sp_diag: &'a Handler, /// the unzipped tree: - stack: Vec<TtFrame>, + stack: SmallVector<TtFrame>, /* for MBE-style macro transcription */ interpolations: HashMap<Ident, Rc<NamedMatch>>, @@ -74,7 +75,7 @@ pub fn new_tt_reader_with_doc_flag(sp_diag: &Handler, -> TtReader { let mut r = TtReader { sp_diag: sp_diag, - stack: vec!(TtFrame { + stack: SmallVector::one(TtFrame { forest: TokenTree::Sequence(DUMMY_SP, Rc::new(tokenstream::SequenceRepetition { tts: src, // doesn't matter. This merely holds the root unzipping. diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 16916ddd5d6..4bf6e55d674 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -972,10 +972,8 @@ pub fn noop_fold_mod<T: Folder>(Mod {inner, items}: Mod, folder: &mut T) -> Mod } } -pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, mut exported_macros, span}: Crate, +pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, mut exported_macros, span}: Crate, folder: &mut T) -> Crate { - let config = folder.fold_meta_items(config); - let mut items = folder.fold_item(P(ast::Item { ident: keywords::Invalid.ident(), attrs: attrs, @@ -1009,7 +1007,6 @@ pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, mut exported_mac Crate { module: module, attrs: attrs, - config: config, exported_macros: exported_macros, span: span, } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index b2f27878993..b86e508d899 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -36,6 +36,7 @@ #![feature(specialization)] #![feature(dotdot_in_tuple_patterns)] +extern crate core; extern crate serialize; extern crate term; extern crate libc; diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 1a84a750463..7b67c23e102 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -10,7 +10,7 @@ //! The main parser interface -use ast; +use ast::{self, CrateConfig}; use codemap::CodeMap; use syntax_pos::{self, Span, FileMap}; use errors::{Handler, ColorConfig, DiagnosticBuilder}; @@ -44,13 +44,14 @@ pub mod obsolete; pub struct ParseSess { pub span_diagnostic: Handler, // better be the same as the one in the reader! pub unstable_features: UnstableFeatures, + pub config: CrateConfig, /// Used to determine and report recursive mod inclusions included_mod_stack: RefCell<Vec<PathBuf>>, code_map: Rc<CodeMap>, } impl ParseSess { - pub fn new() -> ParseSess { + pub fn new() -> Self { let cm = Rc::new(CodeMap::new()); let handler = Handler::with_tty_emitter(ColorConfig::Auto, true, @@ -63,6 +64,7 @@ impl ParseSess { ParseSess { span_diagnostic: handler, unstable_features: UnstableFeatures::from_environment(), + config: Vec::new(), included_mod_stack: RefCell::new(vec![]), code_map: code_map } @@ -78,146 +80,90 @@ impl ParseSess { // uses a HOF to parse anything, and <source> includes file and // source_str. -pub fn parse_crate_from_file<'a>(input: &Path, - cfg: ast::CrateConfig, - sess: &'a ParseSess) - -> PResult<'a, ast::Crate> { - let mut parser = new_parser_from_file(sess, cfg, input); +pub fn parse_crate_from_file<'a>(input: &Path, sess: &'a ParseSess) -> PResult<'a, ast::Crate> { + let mut parser = new_parser_from_file(sess, input); parser.parse_crate_mod() } -pub fn parse_crate_attrs_from_file<'a>(input: &Path, - cfg: ast::CrateConfig, - sess: &'a ParseSess) +pub fn parse_crate_attrs_from_file<'a>(input: &Path, sess: &'a ParseSess) -> PResult<'a, Vec<ast::Attribute>> { - let mut parser = new_parser_from_file(sess, cfg, input); + let mut parser = new_parser_from_file(sess, input); parser.parse_inner_attributes() } -pub fn parse_crate_from_source_str<'a>(name: String, - source: String, - cfg: ast::CrateConfig, - sess: &'a ParseSess) +pub fn parse_crate_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) -> PResult<'a, ast::Crate> { - let mut p = new_parser_from_source_str(sess, - cfg, - name, - source); - p.parse_crate_mod() + new_parser_from_source_str(sess, name, source).parse_crate_mod() } -pub fn parse_crate_attrs_from_source_str<'a>(name: String, - source: String, - cfg: ast::CrateConfig, - sess: &'a ParseSess) +pub fn parse_crate_attrs_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) -> PResult<'a, Vec<ast::Attribute>> { - let mut p = new_parser_from_source_str(sess, - cfg, - name, - source); - p.parse_inner_attributes() + new_parser_from_source_str(sess, name, source).parse_inner_attributes() } -pub fn parse_expr_from_source_str<'a>(name: String, - source: String, - cfg: ast::CrateConfig, - sess: &'a ParseSess) +pub fn parse_expr_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) -> PResult<'a, P<ast::Expr>> { - let mut p = new_parser_from_source_str(sess, cfg, name, source); - p.parse_expr() + new_parser_from_source_str(sess, name, source).parse_expr() } /// Parses an item. /// /// Returns `Ok(Some(item))` when successful, `Ok(None)` when no item was found, and`Err` /// when a syntax error occurred. -pub fn parse_item_from_source_str<'a>(name: String, - source: String, - cfg: ast::CrateConfig, - sess: &'a ParseSess) +pub fn parse_item_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) -> PResult<'a, Option<P<ast::Item>>> { - let mut p = new_parser_from_source_str(sess, cfg, name, source); - p.parse_item() + new_parser_from_source_str(sess, name, source).parse_item() } -pub fn parse_meta_from_source_str<'a>(name: String, - source: String, - cfg: ast::CrateConfig, - sess: &'a ParseSess) +pub fn parse_meta_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) -> PResult<'a, P<ast::MetaItem>> { - let mut p = new_parser_from_source_str(sess, cfg, name, source); - p.parse_meta_item() + new_parser_from_source_str(sess, name, source).parse_meta_item() } -pub fn parse_stmt_from_source_str<'a>(name: String, - source: String, - cfg: ast::CrateConfig, - sess: &'a ParseSess) +pub fn parse_stmt_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) -> PResult<'a, Option<ast::Stmt>> { - let mut p = new_parser_from_source_str( - sess, - cfg, - name, - source - ); - p.parse_stmt() + new_parser_from_source_str(sess, name, source).parse_stmt() } // Warning: This parses with quote_depth > 0, which is not the default. -pub fn parse_tts_from_source_str<'a>(name: String, - source: String, - cfg: ast::CrateConfig, - sess: &'a ParseSess) +pub fn parse_tts_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) -> PResult<'a, Vec<tokenstream::TokenTree>> { - let mut p = new_parser_from_source_str( - sess, - cfg, - name, - source - ); + let mut p = new_parser_from_source_str(sess, name, source); p.quote_depth += 1; // right now this is re-creating the token trees from ... token trees. p.parse_all_token_trees() } // Create a new parser from a source string -pub fn new_parser_from_source_str<'a>(sess: &'a ParseSess, - cfg: ast::CrateConfig, - name: String, - source: String) +pub fn new_parser_from_source_str<'a>(sess: &'a ParseSess, name: String, source: String) -> Parser<'a> { - filemap_to_parser(sess, sess.codemap().new_filemap(name, None, source), cfg) + filemap_to_parser(sess, sess.codemap().new_filemap(name, None, source)) } /// Create a new parser, handling errors as appropriate /// if the file doesn't exist -pub fn new_parser_from_file<'a>(sess: &'a ParseSess, - cfg: ast::CrateConfig, - path: &Path) -> Parser<'a> { - filemap_to_parser(sess, file_to_filemap(sess, path, None), cfg) +pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path) -> Parser<'a> { + filemap_to_parser(sess, file_to_filemap(sess, path, None)) } /// Given a session, a crate config, a path, and a span, add /// the file at the given path to the codemap, and return a parser. /// On an error, use the given span as the source of the problem. pub fn new_sub_parser_from_file<'a>(sess: &'a ParseSess, - cfg: ast::CrateConfig, path: &Path, owns_directory: bool, module_name: Option<String>, sp: Span) -> Parser<'a> { - let mut p = filemap_to_parser(sess, file_to_filemap(sess, path, Some(sp)), cfg); + let mut p = filemap_to_parser(sess, file_to_filemap(sess, path, Some(sp))); p.owns_directory = owns_directory; p.root_module_name = module_name; p } /// Given a filemap and config, return a parser -pub fn filemap_to_parser<'a>(sess: &'a ParseSess, - filemap: Rc<FileMap>, - cfg: ast::CrateConfig) -> Parser<'a> { +pub fn filemap_to_parser<'a>(sess: &'a ParseSess, filemap: Rc<FileMap>, ) -> Parser<'a> { let end_pos = filemap.end_pos; - let mut parser = tts_to_parser(sess, filemap_to_tts(sess, filemap), cfg); + let mut parser = tts_to_parser(sess, filemap_to_tts(sess, filemap)); if parser.token == token::Eof && parser.span == syntax_pos::DUMMY_SP { parser.span = syntax_pos::mk_sp(end_pos, end_pos); @@ -228,18 +174,13 @@ pub fn filemap_to_parser<'a>(sess: &'a ParseSess, // must preserve old name for now, because quote! from the *existing* // compiler expands into it -pub fn new_parser_from_tts<'a>(sess: &'a ParseSess, - cfg: ast::CrateConfig, - tts: Vec<tokenstream::TokenTree>) +pub fn new_parser_from_tts<'a>(sess: &'a ParseSess, tts: Vec<tokenstream::TokenTree>) -> Parser<'a> { - tts_to_parser(sess, tts, cfg) + tts_to_parser(sess, tts) } -pub fn new_parser_from_ts<'a>(sess: &'a ParseSess, - cfg: ast::CrateConfig, - ts: tokenstream::TokenStream) - -> Parser<'a> { - tts_to_parser(sess, ts.to_tts(), cfg) +pub fn new_parser_from_ts<'a>(sess: &'a ParseSess, ts: tokenstream::TokenStream) -> Parser<'a> { + tts_to_parser(sess, ts.to_tts()) } @@ -266,18 +207,15 @@ pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>) -> Vec<tokenstream::TokenTree> { // it appears to me that the cfg doesn't matter here... indeed, // parsing tt's probably shouldn't require a parser at all. - let cfg = Vec::new(); let srdr = lexer::StringReader::new(&sess.span_diagnostic, filemap); - let mut p1 = Parser::new(sess, cfg, Box::new(srdr)); + let mut p1 = Parser::new(sess, Box::new(srdr)); panictry!(p1.parse_all_token_trees()) } -/// Given tts and cfg, produce a parser -pub fn tts_to_parser<'a>(sess: &'a ParseSess, - tts: Vec<tokenstream::TokenTree>, - cfg: ast::CrateConfig) -> Parser<'a> { +/// Given tts and the ParseSess, produce a parser +pub fn tts_to_parser<'a>(sess: &'a ParseSess, tts: Vec<tokenstream::TokenTree>) -> Parser<'a> { let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, tts); - let mut p = Parser::new(sess, cfg, Box::new(trdr)); + let mut p = Parser::new(sess, Box::new(trdr)); p.check_unknown_macro_variable(); p } @@ -1057,13 +995,13 @@ mod tests { let name = "<source>".to_string(); let source = "/// doc comment\r\nfn foo() {}".to_string(); - let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess) + let item = parse_item_from_source_str(name.clone(), source, &sess) .unwrap().unwrap(); let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap(); assert_eq!(&doc[..], "/// doc comment"); let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string(); - let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess) + let item = parse_item_from_source_str(name.clone(), source, &sess) .unwrap().unwrap(); let docs = item.attrs.iter().filter(|a| &*a.name() == "doc") .map(|a| a.value_str().unwrap().to_string()).collect::<Vec<_>>(); @@ -1071,7 +1009,7 @@ mod tests { assert_eq!(&docs[..], b); let source = "/** doc comment\r\n * with CRLF */\r\nfn foo() {}".to_string(); - let item = parse_item_from_source_str(name, source, Vec::new(), &sess).unwrap().unwrap(); + let item = parse_item_from_source_str(name, source, &sess).unwrap().unwrap(); let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap(); assert_eq!(&doc[..], "/** doc comment\n * with CRLF */"); } @@ -1080,7 +1018,7 @@ mod tests { fn ttdelim_span() { let sess = ParseSess::new(); let expr = parse::parse_expr_from_source_str("foo".to_string(), - "foo!( fn main() { body } )".to_string(), vec![], &sess).unwrap(); + "foo!( fn main() { body } )".to_string(), &sess).unwrap(); let tts = match expr.node { ast::ExprKind::Mac(ref mac) => mac.node.tts.clone(), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d8dff6b4aa0..a75937759a2 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -15,7 +15,7 @@ use ast::Unsafety; use ast::{Mod, Arg, Arm, Attribute, BindingMode, TraitItemKind}; use ast::Block; use ast::{BlockCheckMode, CaptureBy}; -use ast::{Constness, Crate, CrateConfig}; +use ast::{Constness, Crate}; use ast::Defaultness; use ast::EnumDef; use ast::{Expr, ExprKind, RangeLimits}; @@ -271,7 +271,6 @@ pub struct Parser<'a> { pub span: Span, /// the span of the previous token: pub prev_span: Span, - pub cfg: CrateConfig, /// the previous token kind prev_token_kind: PrevTokenKind, lookahead_buffer: LookaheadBuffer, @@ -358,11 +357,7 @@ impl From<P<Expr>> for LhsExpr { } impl<'a> Parser<'a> { - pub fn new(sess: &'a ParseSess, - cfg: ast::CrateConfig, - mut rdr: Box<Reader+'a>) - -> Parser<'a> - { + pub fn new(sess: &'a ParseSess, mut rdr: Box<Reader+'a>) -> Self { let tok0 = rdr.real_token(); let span = tok0.sp; let mut directory = match span { @@ -374,7 +369,6 @@ impl<'a> Parser<'a> { Parser { reader: rdr, sess: sess, - cfg: cfg, token: tok0.tok, span: span, prev_span: span, @@ -1757,6 +1751,17 @@ impl<'a> Parser<'a> { // First, parse an identifier. let identifier = self.parse_path_segment_ident()?; + if self.check(&token::ModSep) && self.look_ahead(1, |t| *t == token::Lt) { + self.bump(); + let prev_span = self.prev_span; + + let mut err = self.diagnostic().struct_span_err(prev_span, + "unexpected token: `::`"); + err.help( + "use `<...>` instead of `::<...>` if you meant to specify type arguments"); + err.emit(); + } + // Parse types, optionally. let parameters = if self.eat_lt() { let (lifetimes, types, bindings) = self.parse_generic_values_after_lt()?; @@ -5317,7 +5322,6 @@ impl<'a> Parser<'a> { fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo> { let (in_cfg, outer_attrs) = { let mut strip_unconfigured = ::config::StripUnconfigured { - config: &self.cfg, sess: self.sess, should_test: false, // irrelevant features: None, // don't perform gated feature checking @@ -5485,12 +5489,7 @@ impl<'a> Parser<'a> { included_mod_stack.push(path.clone()); drop(included_mod_stack); - let mut p0 = new_sub_parser_from_file(self.sess, - self.cfg.clone(), - &path, - owns_directory, - Some(name), - id_sp); + let mut p0 = new_sub_parser_from_file(self.sess, &path, owns_directory, Some(name), id_sp); let mod_inner_lo = p0.span.lo; let mod_attrs = p0.parse_inner_attributes()?; let m0 = p0.parse_mod_items(&token::Eof, mod_inner_lo)?; @@ -6134,15 +6133,20 @@ impl<'a> Parser<'a> { /// MOD_SEP? LBRACE item_seq RBRACE fn parse_view_path(&mut self) -> PResult<'a, P<ViewPath>> { let lo = self.span.lo; - if self.check(&token::OpenDelim(token::Brace)) || self.is_import_coupler() { - // `{foo, bar}` or `::{foo, bar}` + if self.check(&token::OpenDelim(token::Brace)) || self.check(&token::BinOp(token::Star)) || + self.is_import_coupler() { + // `{foo, bar}`, `::{foo, bar}`, `*`, or `::*`. let prefix = ast::Path { global: self.eat(&token::ModSep), segments: Vec::new(), span: mk_sp(lo, self.span.hi), }; - let items = self.parse_path_list_items()?; - Ok(P(spanned(lo, self.span.hi, ViewPathList(prefix, items)))) + let view_path_kind = if self.eat(&token::BinOp(token::Star)) { + ViewPathGlob(prefix) + } else { + ViewPathList(prefix, self.parse_path_list_items()?) + }; + Ok(P(spanned(lo, self.span.hi, view_path_kind))) } else { let prefix = self.parse_path(PathStyle::Mod)?; if self.is_import_coupler() { @@ -6179,7 +6183,6 @@ impl<'a> Parser<'a> { Ok(ast::Crate { attrs: self.parse_inner_attributes()?, module: self.parse_mod_items(&token::Eof, lo)?, - config: self.cfg.clone(), span: mk_sp(lo, self.span.lo), exported_macros: Vec::new(), }) diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 8faad77859e..fdc1f45623d 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -274,7 +274,7 @@ fn generate_test_harness(sess: &ParseSess, let mut cx: TestCtxt = TestCtxt { sess: sess, span_diagnostic: sd, - ext_cx: ExtCtxt::new(sess, vec![], ExpansionConfig::default("test".to_string()), resolver), + ext_cx: ExtCtxt::new(sess, ExpansionConfig::default("test".to_string()), resolver), path: Vec::new(), testfns: Vec::new(), reexport_test_harness_main: reexport_test_harness_main, diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index f22f920a7fa..9e644e59e86 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -220,7 +220,7 @@ impl TokenTree { None, tts.iter().cloned().collect(), true); - macro_parser::parse(cx.parse_sess(), cx.cfg(), arg_rdr, mtch) + macro_parser::parse(cx.parse_sess(), arg_rdr, mtch) } /// Check if this TokenTree is equal to the other, regardless of span information. diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index f59428bf536..76d3f2a063c 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -25,10 +25,7 @@ pub fn string_to_tts(source_str: String) -> Vec<tokenstream::TokenTree> { /// Map string to parser (via tts) pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> { - new_parser_from_source_str(ps, - Vec::new(), - "bogofile".to_string(), - source_str) + new_parser_from_source_str(ps, "bogofile".to_string(), source_str) } fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T where diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index 373dfc4ddfa..57258c76335 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -11,6 +11,7 @@ use self::SmallVectorRepr::*; use self::IntoIterRepr::*; +use core::ops; use std::iter::{IntoIterator, FromIterator}; use std::mem; use std::slice; @@ -19,10 +20,12 @@ use std::vec; use util::move_map::MoveMap; /// A vector type optimized for cases where the size is almost always 0 or 1 +#[derive(Clone)] pub struct SmallVector<T> { repr: SmallVectorRepr<T>, } +#[derive(Clone)] enum SmallVectorRepr<T> { Zero, One(T), @@ -75,16 +78,11 @@ impl<T> SmallVector<T> { } pub fn as_slice(&self) -> &[T] { - match self.repr { - Zero => { - let result: &[T] = &[]; - result - } - One(ref v) => { - unsafe { slice::from_raw_parts(v, 1) } - } - Many(ref vs) => vs - } + self + } + + pub fn as_mut_slice(&mut self) -> &mut [T] { + self } pub fn pop(&mut self) -> Option<T> { @@ -163,6 +161,38 @@ impl<T> SmallVector<T> { } } +impl<T> ops::Deref for SmallVector<T> { + type Target = [T]; + + fn deref(&self) -> &[T] { + match self.repr { + Zero => { + let result: &[T] = &[]; + result + } + One(ref v) => { + unsafe { slice::from_raw_parts(v, 1) } + } + Many(ref vs) => vs + } + } +} + +impl<T> ops::DerefMut for SmallVector<T> { + fn deref_mut(&mut self) -> &mut [T] { + match self.repr { + Zero => { + let result: &mut [T] = &mut []; + result + } + One(ref mut v) => { + unsafe { slice::from_raw_parts_mut(v, 1) } + } + Many(ref mut vs) => vs + } + } +} + impl<T> IntoIterator for SmallVector<T> { type Item = T; type IntoIter = IntoIter<T>; diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs index 1c97099d387..24c515e5028 100644 --- a/src/libsyntax_ext/asm.rs +++ b/src/libsyntax_ext/asm.rs @@ -107,7 +107,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, if p2.token != token::Eof { let mut extra_tts = panictry!(p2.parse_all_token_trees()); extra_tts.extend(tts[first_colon..].iter().cloned()); - p = parse::tts_to_parser(cx.parse_sess, extra_tts, cx.cfg().clone()); + p = parse::tts_to_parser(cx.parse_sess, extra_tts); } asm = s; diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs index 169ef9ab7d6..98da49545f9 100644 --- a/src/libsyntax_ext/cfg.rs +++ b/src/libsyntax_ext/cfg.rs @@ -32,6 +32,6 @@ pub fn expand_cfg<'cx>(cx: &mut ExtCtxt, return DummyResult::expr(sp); } - let matches_cfg = attr::cfg_matches(&cx.cfg, &cfg, cx.parse_sess, cx.ecfg.features); + let matches_cfg = attr::cfg_matches(&cfg, cx.parse_sess, cx.ecfg.features); MacEager::expr(cx.expr_bool(sp, matches_cfg)) } diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index bc47d8f4e61..687f8c902f2 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -1460,8 +1460,9 @@ impl<'a> MethodDef<'a> { .iter() .map(|v| { let ident = v.node.name; + let sp = Span { expn_id: trait_.span.expn_id, ..v.span }; let summary = trait_.summarise_struct(cx, &v.node.data); - (ident, v.span, summary) + (ident, sp, summary) }) .collect(); self.call_substructure_method(cx, diff --git a/src/libsyntax_ext/proc_macro_registrar.rs b/src/libsyntax_ext/proc_macro_registrar.rs index b96fb08e59e..f49a5f0e070 100644 --- a/src/libsyntax_ext/proc_macro_registrar.rs +++ b/src/libsyntax_ext/proc_macro_registrar.rs @@ -47,7 +47,7 @@ pub fn modify(sess: &ParseSess, handler: &errors::Handler, features: &Features) -> ast::Crate { let ecfg = ExpansionConfig::default("proc_macro".to_string()); - let mut cx = ExtCtxt::new(sess, Vec::new(), ecfg, resolver); + let mut cx = ExtCtxt::new(sess, ecfg, resolver); let mut collect = CollectCustomDerives { derives: Vec::new(), diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index e3feaee5369..d83d3a6c5cf 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -481,6 +481,9 @@ impl FileMap { self.src.is_none() } + pub fn byte_length(&self) -> u32 { + self.end_pos.0 - self.start_pos.0 + } pub fn count_lines(&self) -> usize { self.lines.borrow().len() } diff --git a/src/llvm b/src/llvm -Subproject 8c9961a9cc406c9bcb29a8752a4a2ad9f5f98b1 +Subproject c1d962263bf76a10bea0c761621fcd98d6214b2 diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index 0f63d70af9d..37fded948e1 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2016-10-18 +2016-10-29 diff --git a/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs b/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs index 2041abcf82c..60697cc8b6a 100644 --- a/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs +++ b/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs @@ -56,8 +56,7 @@ fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) fn expand_identity(cx: &mut ExtCtxt, _span: Span, tts: &[TokenTree]) -> Box<MacResult+'static> { // Parse an expression and emit it unchanged. - let mut parser = parse::new_parser_from_tts(cx.parse_sess(), - cx.cfg().clone(), tts.to_vec()); + let mut parser = parse::new_parser_from_tts(cx.parse_sess(), tts.to_vec()); let expr = parser.parse_expr().unwrap(); MacEager::expr(quote_expr!(&mut *cx, $expr)) } diff --git a/src/test/compile-fail-fulldeps/issue-18986.rs b/src/test/compile-fail-fulldeps/issue-18986.rs index 3c32cb947b3..95af3760544 100644 --- a/src/test/compile-fail-fulldeps/issue-18986.rs +++ b/src/test/compile-fail-fulldeps/issue-18986.rs @@ -15,6 +15,6 @@ pub use use_from_trait_xc::Trait; fn main() { match () { - Trait { x: 42 } => () //~ ERROR expected variant, struct or type alias, found trait `Trait` + Trait { x: 42 } => () //~ ERROR expected struct, variant or union type, found trait `Trait` } } diff --git a/src/test/compile-fail-fulldeps/qquote.rs b/src/test/compile-fail-fulldeps/qquote.rs index 3e5d17e2ffb..4a7033d44b8 100644 --- a/src/test/compile-fail-fulldeps/qquote.rs +++ b/src/test/compile-fail-fulldeps/qquote.rs @@ -24,7 +24,7 @@ fn main() { let ps = syntax::parse::ParseSess::new(); let mut resolver = syntax::ext::base::DummyResolver; let mut cx = syntax::ext::base::ExtCtxt::new( - &ps, vec![], + &ps, syntax::ext::expand::ExpansionConfig::default("qquote".to_string()), &mut resolver); cx.bt_push(syntax::codemap::ExpnInfo { diff --git a/src/test/compile-fail/E0071.rs b/src/test/compile-fail/E0071.rs index c13ba7bf136..95653ae83e7 100644 --- a/src/test/compile-fail/E0071.rs +++ b/src/test/compile-fail/E0071.rs @@ -9,13 +9,10 @@ // except according to those terms. enum Foo {} +type FooAlias = Foo; fn main() { - let u = Foo { value: 0 }; - //~^ ERROR `Foo` does not name a struct or a struct variant [E0071] - //~| NOTE not a struct - - let t = u32 { value: 4 }; - //~^ ERROR `u32` does not name a struct or a struct variant [E0071] + let u = FooAlias { value: 0 }; + //~^ ERROR expected struct, variant or union type, found enum `Foo` [E0071] //~| NOTE not a struct } diff --git a/src/test/compile-fail/enums-are-namespaced-xc.rs b/src/test/compile-fail/enums-are-namespaced-xc.rs index 5315e6c834a..02939565f69 100644 --- a/src/test/compile-fail/enums-are-namespaced-xc.rs +++ b/src/test/compile-fail/enums-are-namespaced-xc.rs @@ -14,5 +14,6 @@ extern crate namespaced_enums; fn main() { let _ = namespaced_enums::A; //~ ERROR unresolved name let _ = namespaced_enums::B(10); //~ ERROR unresolved name - let _ = namespaced_enums::C { a: 10 }; //~ ERROR does not name a structure + let _ = namespaced_enums::C { a: 10 }; + //~^ ERROR unresolved struct, variant or union type `namespaced_enums::C` } diff --git a/src/test/compile-fail/issue-12612.rs b/src/test/compile-fail/issue-12612.rs index 20943bd0ea0..c6f76ca7887 100644 --- a/src/test/compile-fail/issue-12612.rs +++ b/src/test/compile-fail/issue-12612.rs @@ -16,7 +16,7 @@ use foo::bar; mod test { use bar::foo; //~ ERROR unresolved import `bar::foo` [E0432] - //~^ Maybe a missing `extern crate bar`? + //~^ Maybe a missing `extern crate bar;`? } fn main() {} diff --git a/src/test/compile-fail/issue-16058.rs b/src/test/compile-fail/issue-16058.rs index 671232e701f..92c1e4b5f50 100644 --- a/src/test/compile-fail/issue-16058.rs +++ b/src/test/compile-fail/issue-16058.rs @@ -16,7 +16,7 @@ pub struct GslResult { impl GslResult { pub fn new() -> GslResult { - Result { //~ ERROR: `Result` does not name a struct or a struct variant + Result { //~ ERROR: expected struct, variant or union type, found enum `Result` val: 0f64, err: 0f64 } diff --git a/src/test/compile-fail/issue-1697.rs b/src/test/compile-fail/issue-1697.rs index dc09af0ada6..1375200271c 100644 --- a/src/test/compile-fail/issue-1697.rs +++ b/src/test/compile-fail/issue-1697.rs @@ -11,6 +11,6 @@ // Testing that we don't fail abnormally after hitting the errors use unresolved::*; //~ ERROR unresolved import `unresolved::*` [E0432] - //~^ Maybe a missing `extern crate unresolved`? + //~^ Maybe a missing `extern crate unresolved;`? fn main() {} diff --git a/src/test/compile-fail/issue-17001.rs b/src/test/compile-fail/issue-17001.rs index 218f68714ff..413e8b464ff 100644 --- a/src/test/compile-fail/issue-17001.rs +++ b/src/test/compile-fail/issue-17001.rs @@ -11,5 +11,5 @@ mod foo {} fn main() { - let p = foo { x: () }; //~ ERROR `foo` does not name a struct or a struct variant + let p = foo { x: () }; //~ ERROR expected struct, variant or union type, found module `foo` } diff --git a/src/test/compile-fail/issue-17405.rs b/src/test/compile-fail/issue-17405.rs index 2f2c252b947..5a6bd5ed588 100644 --- a/src/test/compile-fail/issue-17405.rs +++ b/src/test/compile-fail/issue-17405.rs @@ -14,6 +14,6 @@ enum Foo { fn main() { match Foo::Bar(1) { - Foo { i } => () //~ ERROR expected variant, struct or type alias, found enum `Foo` + Foo { i } => () //~ ERROR expected struct, variant or union type, found enum `Foo` } } diff --git a/src/test/compile-fail/issue-17518.rs b/src/test/compile-fail/issue-17518.rs index 0410fadeb78..2113e38c45c 100644 --- a/src/test/compile-fail/issue-17518.rs +++ b/src/test/compile-fail/issue-17518.rs @@ -13,5 +13,5 @@ enum SomeEnum { } fn main() { - E { name: "foobar" }; //~ ERROR `E` does not name a structure + E { name: "foobar" }; //~ ERROR unresolved struct, variant or union type `E` } diff --git a/src/test/compile-fail/issue-21449.rs b/src/test/compile-fail/issue-21449.rs index 090b8a0d16e..cc44cf88f09 100644 --- a/src/test/compile-fail/issue-21449.rs +++ b/src/test/compile-fail/issue-21449.rs @@ -11,5 +11,6 @@ mod MyMod {} fn main() { - let myVar = MyMod { T: 0 }; //~ ERROR `MyMod` does not name a struct or a struct variant + let myVar = MyMod { T: 0 }; + //~^ ERROR expected struct, variant or union type, found module `MyMod` } diff --git a/src/test/compile-fail/issue-26459.rs b/src/test/compile-fail/issue-26459.rs index 24b39eeff0f..8be3d88bd5c 100644 --- a/src/test/compile-fail/issue-26459.rs +++ b/src/test/compile-fail/issue-26459.rs @@ -11,6 +11,6 @@ fn main() { match 'a' { char{ch} => true - //~^ ERROR expected variant, struct or type alias, found builtin type `char` + //~^ ERROR expected struct, variant or union type, found builtin type `char` }; } diff --git a/src/test/compile-fail/issue-27815.rs b/src/test/compile-fail/issue-27815.rs index 33930d1db14..d9840abf0ca 100644 --- a/src/test/compile-fail/issue-27815.rs +++ b/src/test/compile-fail/issue-27815.rs @@ -11,12 +11,12 @@ mod A {} fn main() { - let u = A { x: 1 }; //~ ERROR `A` does not name a struct or a struct variant - let v = u32 { x: 1 }; //~ ERROR `u32` does not name a struct or a struct variant + let u = A { x: 1 }; //~ ERROR expected struct, variant or union type, found module `A` + let v = u32 { x: 1 }; //~ ERROR expected struct, variant or union type, found builtin type `u32` match () { A { x: 1 } => {} - //~^ ERROR expected variant, struct or type alias, found module `A` + //~^ ERROR expected struct, variant or union type, found module `A` u32 { x: 1 } => {} - //~^ ERROR expected variant, struct or type alias, found builtin type `u32` + //~^ ERROR expected struct, variant or union type, found builtin type `u32` } } diff --git a/src/test/compile-fail/issue-36116.rs b/src/test/compile-fail/issue-36116.rs new file mode 100644 index 00000000000..9abf2b5ec3a --- /dev/null +++ b/src/test/compile-fail/issue-36116.rs @@ -0,0 +1,23 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Foo<T> { + _a: T, +} + +fn main() { + let f = Some(Foo { _a: 42 }).map(|a| a as Foo::<i32>); + //~^ ERROR unexpected token: `::` + //~| HELP use `<...>` instead of `::<...>` if you meant to specify type arguments + + let g: Foo::<i32> = Foo { _a: 42 }; + //~^ ERROR unexpected token: `::` + //~| HELP use `<...>` instead of `::<...>` if you meant to specify type arguments +} diff --git a/src/test/compile-fail/lexical-scopes.rs b/src/test/compile-fail/lexical-scopes.rs index 505a91f223c..1ab59e790d7 100644 --- a/src/test/compile-fail/lexical-scopes.rs +++ b/src/test/compile-fail/lexical-scopes.rs @@ -10,7 +10,7 @@ struct T { i: i32 } fn f<T>() { - let t = T { i: 0 }; //~ ERROR `T` does not name a struct or a struct variant + let t = T { i: 0 }; //~ ERROR expected struct, variant or union type, found type parameter `T` } mod Foo { diff --git a/src/test/compile-fail/no-patterns-in-args-2.rs b/src/test/compile-fail/no-patterns-in-args-2.rs new file mode 100644 index 00000000000..385d012cade --- /dev/null +++ b/src/test/compile-fail/no-patterns-in-args-2.rs @@ -0,0 +1,23 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![deny(patterns_in_fns_without_body)] + +trait Tr { + fn f1(mut arg: u8); //~ ERROR patterns aren't allowed in methods without bodies + //~^ WARN was previously accepted + fn f2(&arg: u8); //~ ERROR patterns aren't allowed in methods without bodies + //~^ WARN was previously accepted + fn g1(arg: u8); // OK + fn g2(_: u8); // OK + fn g3(u8); // OK +} + +fn main() {} diff --git a/src/test/compile-fail/E0422.rs b/src/test/compile-fail/struct-path-alias-bounds.rs index 61e96b896a6..1b6e51e3703 100644 --- a/src/test/compile-fail/E0422.rs +++ b/src/test/compile-fail/struct-path-alias-bounds.rs @@ -8,8 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn main () { - let x = Foo { x: 1, y: 2 }; - //~^ ERROR E0422 - //~| NOTE not a structure +// issue #36286 + +struct S<T: Clone> { a: T } + +struct NoClone; +type A = S<NoClone>; + +fn main() { + let s = A { a: NoClone }; + //~^ ERROR the trait bound `NoClone: std::clone::Clone` is not satisfied } diff --git a/src/test/compile-fail/struct-path-associated-type.rs b/src/test/compile-fail/struct-path-associated-type.rs new file mode 100644 index 00000000000..660ac44ce0b --- /dev/null +++ b/src/test/compile-fail/struct-path-associated-type.rs @@ -0,0 +1,48 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct S; + +trait Tr { + type A; +} + +impl Tr for S { + type A = S; +} + +fn f<T: Tr>() { + let s = T::A {}; + //~^ ERROR expected struct, variant or union type, found associated type + let z = T::A::<u8> {}; + //~^ ERROR expected struct, variant or union type, found associated type + //~| ERROR type parameters are not allowed on this type + match S { + T::A {} => {} + //~^ ERROR expected struct, variant or union type, found associated type + } +} + +fn g<T: Tr<A = S>>() { + let s = T::A {}; // OK + let z = T::A::<u8> {}; //~ ERROR type parameters are not allowed on this type + match S { + T::A {} => {} // OK + } +} + +fn main() { + let s = S::A {}; //~ ERROR ambiguous associated type + let z = S::A::<u8> {}; //~ ERROR ambiguous associated type + //~^ ERROR type parameters are not allowed on this type + match S { + S::A {} => {} //~ ERROR ambiguous associated type + } +} diff --git a/src/test/compile-fail/struct-path-self-type-mismatch.rs b/src/test/compile-fail/struct-path-self-type-mismatch.rs new file mode 100644 index 00000000000..f694e7d277c --- /dev/null +++ b/src/test/compile-fail/struct-path-self-type-mismatch.rs @@ -0,0 +1,38 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Foo<A> { inner: A } + +trait Bar { fn bar(); } + +impl Bar for Foo<i32> { + fn bar() { + Self { inner: 1.5f32 }; //~ ERROR mismatched types + //~^ NOTE expected i32, found f32 + } +} + +impl<T> Foo<T> { + fn new<U>(u: U) -> Foo<U> { + Self { + //~^ ERROR mismatched types + //~| expected type parameter, found a different type parameter + //~| expected type `Foo<U>` + //~| found type `Foo<T>` + inner: u + //~^ ERROR mismatched types + //~| expected type parameter, found a different type parameter + //~| expected type `T` + //~| found type `U` + } + } +} + +fn main() {} diff --git a/src/test/compile-fail/struct-path-self.rs b/src/test/compile-fail/struct-path-self.rs new file mode 100644 index 00000000000..067d6ac22dc --- /dev/null +++ b/src/test/compile-fail/struct-path-self.rs @@ -0,0 +1,47 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct S; + +trait Tr { + fn f() { + let s = Self {}; + //~^ ERROR expected struct, variant or union type, found Self + let z = Self::<u8> {}; + //~^ ERROR expected struct, variant or union type, found Self + //~| ERROR type parameters are not allowed on this type + match s { + Self { .. } => {} + //~^ ERROR expected struct, variant or union type, found Self + } + } +} + +impl Tr for S { + fn f() { + let s = Self {}; // OK + let z = Self::<u8> {}; //~ ERROR type parameters are not allowed on this type + match s { + Self { .. } => {} // OK + } + } +} + +impl S { + fn g() { + let s = Self {}; // OK + let z = Self::<u8> {}; //~ ERROR type parameters are not allowed on this type + match s { + Self { .. } => {} // OK + } + } +} + +fn main() {} diff --git a/src/test/compile-fail/trait-as-struct-constructor.rs b/src/test/compile-fail/trait-as-struct-constructor.rs index c78eebddbfd..49d58580da5 100644 --- a/src/test/compile-fail/trait-as-struct-constructor.rs +++ b/src/test/compile-fail/trait-as-struct-constructor.rs @@ -12,6 +12,5 @@ trait TraitNotAStruct {} fn main() { TraitNotAStruct{ value: 0 }; - //~^ ERROR: `TraitNotAStruct` does not name a struct or a struct variant [E0071] - //~| NOTE not a struct + //~^ ERROR expected struct, variant or union type, found trait `TraitNotAStruct` } diff --git a/src/test/compile-fail/unresolved-import.rs b/src/test/compile-fail/unresolved-import.rs index 0a9a4375697..47490af0ff3 100644 --- a/src/test/compile-fail/unresolved-import.rs +++ b/src/test/compile-fail/unresolved-import.rs @@ -11,7 +11,7 @@ // ignore-tidy-linelength use foo::bar; //~ ERROR unresolved import `foo::bar` [E0432] - //~^ Maybe a missing `extern crate foo`? + //~^ Maybe a missing `extern crate foo;`? use bar::Baz as x; //~ ERROR unresolved import `bar::Baz` [E0432] //~^ no `Baz` in `bar`. Did you mean to use `Bar`? diff --git a/src/test/incremental/hashes/trait_defs.rs b/src/test/incremental/hashes/trait_defs.rs index 937f053e320..391c2e75ba4 100644 --- a/src/test/incremental/hashes/trait_defs.rs +++ b/src/test/incremental/hashes/trait_defs.rs @@ -264,8 +264,8 @@ trait TraitChangeModeSelfRefToMut { #[cfg(cfail1)] -trait TraitChangeModeSelfOwnToMut { - fn method(self); +trait TraitChangeModeSelfOwnToMut: Sized { + fn method(self) {} } #[cfg(not(cfail1))] @@ -273,8 +273,8 @@ trait TraitChangeModeSelfOwnToMut { #[rustc_clean(label="Hir", cfg="cfail3")] #[rustc_metadata_dirty(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] -trait TraitChangeModeSelfOwnToMut { - fn method(mut self); +trait TraitChangeModeSelfOwnToMut: Sized { + fn method(mut self) {} } diff --git a/src/test/run-fail-fulldeps/qquote.rs b/src/test/run-fail-fulldeps/qquote.rs index 1458583ff58..d2a16ac7507 100644 --- a/src/test/run-fail-fulldeps/qquote.rs +++ b/src/test/run-fail-fulldeps/qquote.rs @@ -27,7 +27,7 @@ fn main() { let ps = syntax::parse::ParseSess::new(); let mut resolver = syntax::ext::base::DummyResolver; let mut cx = syntax::ext::base::ExtCtxt::new( - &ps, vec![], + &ps, syntax::ext::expand::ExpansionConfig::default("qquote".to_string()), &mut resolver); cx.bt_push(syntax::codemap::ExpnInfo { diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs index 35043bdaddf..ed127b017b6 100644 --- a/src/test/run-make/issue-19371/foo.rs +++ b/src/test/run-make/issue-19371/foo.rs @@ -67,12 +67,6 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { let (sess, cstore) = basic_sess(sysroot); let cfg = build_configuration(&sess, vec![]); let control = CompileController::basic(); - - compile_input(&sess, &cstore, - cfg, - &Input::Str { name: anon_src(), input: code }, - &None, - &Some(output), - None, - &control); + let input = Input::Str { name: anon_src(), input: code }; + compile_input(&sess, &cstore, &input, &None, &Some(output), None, &control); } diff --git a/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs b/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs index 64747002a65..a41b34f6a53 100644 --- a/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs +++ b/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs @@ -31,10 +31,7 @@ use std::fmt; // Copied out of syntax::util::parser_testing pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> { - new_parser_from_source_str(ps, - Vec::new(), - "bogofile".to_string(), - source_str) + new_parser_from_source_str(ps, "bogofile".to_string(), source_str) } fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> PResult<'a, T> where diff --git a/src/test/run-pass-fulldeps/auxiliary/cond_noprelude_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/cond_noprelude_plugin.rs index 78589546084..48919fe876a 100644 --- a/src/test/run-pass-fulldeps/auxiliary/cond_noprelude_plugin.rs +++ b/src/test/run-pass-fulldeps/auxiliary/cond_noprelude_plugin.rs @@ -15,10 +15,10 @@ #![plugin(proc_macro_plugin)] extern crate rustc_plugin; -extern crate proc_macro_plugin; +extern crate proc_macro_tokens; extern crate syntax; -use proc_macro_plugin::build::ident_eq; +use proc_macro_tokens::build::ident_eq; use syntax::ext::base::{ExtCtxt, MacResult}; use syntax::ext::proc_macro_shim::build_block_emitter; diff --git a/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs index 11322bf76ff..0ea4cec75cd 100644 --- a/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs +++ b/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs @@ -15,10 +15,10 @@ #![plugin(proc_macro_plugin)] extern crate rustc_plugin; -extern crate proc_macro_plugin; +extern crate proc_macro_tokens; extern crate syntax; -use proc_macro_plugin::prelude::*; +use proc_macro_tokens::prelude::*; use rustc_plugin::Registry; diff --git a/src/test/run-pass-fulldeps/auxiliary/cond_prelude_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/cond_prelude_plugin.rs index 232a7166e3b..169c96b4385 100644 --- a/src/test/run-pass-fulldeps/auxiliary/cond_prelude_plugin.rs +++ b/src/test/run-pass-fulldeps/auxiliary/cond_prelude_plugin.rs @@ -15,11 +15,11 @@ #![plugin(proc_macro_plugin)] extern crate rustc_plugin; -extern crate proc_macro_plugin; +extern crate proc_macro_tokens; extern crate syntax; use syntax::ext::proc_macro_shim::prelude::*; -use proc_macro_plugin::prelude::*; +use proc_macro_tokens::prelude::*; use rustc_plugin::Registry; diff --git a/src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs b/src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs index f7b046b30ca..3bc4a40a39c 100644 --- a/src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs +++ b/src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs @@ -19,7 +19,7 @@ extern crate rustc_const_math; extern crate syntax; use rustc::mir::transform::{self, MirPass, MirSource}; -use rustc::mir::repr::{Mir, Literal, Location}; +use rustc::mir::{Mir, Literal, Location}; use rustc::mir::visit::MutVisitor; use rustc::ty::TyCtxt; use rustc::middle::const_val::ConstVal; diff --git a/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs b/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs index 2c814a5433b..15ec0ccae8f 100644 --- a/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs +++ b/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs @@ -60,7 +60,7 @@ fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<MacResu // See Issue #15750 fn expand_identity(cx: &mut ExtCtxt, _span: Span, tts: &[TokenTree]) -> Box<MacResult + 'static> { // Parse an expression and emit it unchanged. - let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg().clone(), tts.to_vec()); + let mut parser = parse::new_parser_from_tts(cx.parse_sess(), tts.to_vec()); let expr = parser.parse_expr().unwrap(); MacEager::expr(quote_expr!(&mut *cx, $expr)) } diff --git a/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs b/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs index 961df6d5c0c..9fce19f46f6 100644 --- a/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs +++ b/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs @@ -10,11 +10,11 @@ #![feature(plugin, plugin_registrar, rustc_private)] -extern crate proc_macro_plugin; +extern crate proc_macro_tokens; extern crate rustc_plugin; extern crate syntax; -use proc_macro_plugin::prelude::*; +use proc_macro_tokens::prelude::*; use rustc_plugin::Registry; use syntax::ext::base::SyntaxExtension; use syntax::ext::proc_macro_shim::prelude::*; diff --git a/src/test/run-pass-fulldeps/compiler-calls.rs b/src/test/run-pass-fulldeps/compiler-calls.rs index 35e9f3f5c8d..4a397621ceb 100644 --- a/src/test/run-pass-fulldeps/compiler-calls.rs +++ b/src/test/run-pass-fulldeps/compiler-calls.rs @@ -47,7 +47,6 @@ impl<'a> CompilerCalls<'a> for TestCalls { fn late_callback(&mut self, _: &getopts::Matches, _: &Session, - _: &ast::CrateConfig, _: &Input, _: &Option<PathBuf>, _: &Option<PathBuf>) diff --git a/src/test/run-pass-fulldeps/macro-quote-1.rs b/src/test/run-pass-fulldeps/macro-quote-1.rs index a5ac546cba4..914da3f7467 100644 --- a/src/test/run-pass-fulldeps/macro-quote-1.rs +++ b/src/test/run-pass-fulldeps/macro-quote-1.rs @@ -14,8 +14,8 @@ #![feature(rustc_private)] #![plugin(proc_macro_plugin)] -extern crate proc_macro_plugin; -use proc_macro_plugin::prelude::*; +extern crate proc_macro_tokens; +use proc_macro_tokens::prelude::*; extern crate syntax; use syntax::ast::Ident; diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs index 2a53a62a5ab..7c0c24163fe 100644 --- a/src/test/run-pass-fulldeps/qquote.rs +++ b/src/test/run-pass-fulldeps/qquote.rs @@ -23,7 +23,7 @@ fn main() { let ps = syntax::parse::ParseSess::new(); let mut resolver = syntax::ext::base::DummyResolver; let mut cx = syntax::ext::base::ExtCtxt::new( - &ps, vec![], + &ps, syntax::ext::expand::ExpansionConfig::default("qquote".to_string()), &mut resolver); cx.bt_push(syntax::codemap::ExpnInfo { diff --git a/src/test/run-pass/by-value-self-in-mut-slot.rs b/src/test/run-pass/by-value-self-in-mut-slot.rs index 5bbdec95b15..846b695c35b 100644 --- a/src/test/run-pass/by-value-self-in-mut-slot.rs +++ b/src/test/run-pass/by-value-self-in-mut-slot.rs @@ -14,7 +14,7 @@ struct X { } trait Changer { - fn change(mut self) -> Self; + fn change(self) -> Self; } impl Changer for X { diff --git a/src/test/run-pass/import-glob-crate.rs b/src/test/run-pass/import-glob-crate.rs index b2a9b08b01b..fec46c7e1f8 100644 --- a/src/test/run-pass/import-glob-crate.rs +++ b/src/test/run-pass/import-glob-crate.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![allow(dead_assignment)] - use std::mem::*; pub fn main() { @@ -20,3 +17,12 @@ pub fn main() { assert_eq!(x, 2); assert_eq!(y, 1); } + +#[allow(unused)] +fn f() { + mod foo { pub use *; } + mod bar { pub use ::*; } + + foo::main(); + bar::main(); +} diff --git a/src/test/run-pass/issue-22546.rs b/src/test/run-pass/issue-22546.rs index b3cb8a78213..8516d344e1c 100644 --- a/src/test/run-pass/issue-22546.rs +++ b/src/test/run-pass/issue-22546.rs @@ -51,4 +51,10 @@ fn main() { if let None::<u8> = Some(8) { panic!(); } + if let None::<u8> { .. } = Some(8) { + panic!(); + } + if let Option::None::<u8> { .. } = Some(8) { + panic!(); + } } diff --git a/src/test/compile-fail/struct-pat-associated-path.rs b/src/test/run-pass/struct-path-associated-type.rs index d3f840f4fe9..b033ed5c802 100644 --- a/src/test/compile-fail/struct-pat-associated-path.rs +++ b/src/test/run-pass/struct-path-associated-type.rs @@ -8,30 +8,28 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct S; +struct S<T, U = u16> { + a: T, + b: U, +} trait Tr { type A; } - -impl Tr for S { - type A = S; -} - -fn f<T: Tr>() { - match S { - T::A {} => {} //~ ERROR `T::A` does not name a struct or a struct variant - } +impl Tr for u8 { + type A = S<u8, u16>; } -fn g<T: Tr<A = S>>() { - match S { - T::A {} => {} //~ ERROR `T::A` does not name a struct or a struct variant +fn f<T: Tr<A = S<u8>>>() { + let s = T::A { a: 0, b: 1 }; + match s { + T::A { a, b } => { + assert_eq!(a, 0); + assert_eq!(b, 1); + } } } fn main() { - match S { - S::A {} => {} //~ ERROR ambiguous associated type - } + f::<u8>(); } diff --git a/src/test/run-pass/struct-path-self.rs b/src/test/run-pass/struct-path-self.rs new file mode 100644 index 00000000000..c7a282c2a2f --- /dev/null +++ b/src/test/run-pass/struct-path-self.rs @@ -0,0 +1,54 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::ops::Add; + +struct S<T, U = u16> { + a: T, + b: U, +} + +trait Tr { + fn f(&self) -> Self; +} + +impl<T: Default + Add<u8, Output = T>, U: Default> Tr for S<T, U> { + fn f(&self) -> Self { + let s = Self { a: Default::default(), b: Default::default() }; + match s { + Self { a, b } => Self { a: a + 1, b: b } + } + } +} + +impl<T: Default, U: Default + Add<u16, Output = U>> S<T, U> { + fn g(&self) -> Self { + let s = Self { a: Default::default(), b: Default::default() }; + match s { + Self { a, b } => Self { a: a, b: b + 1 } + } + } +} + +impl S<u8> { + fn new() -> Self { + Self { a: 0, b: 1 } + } +} + +fn main() { + let s0 = S::new(); + let s1 = s0.f(); + assert_eq!(s1.a, 1); + assert_eq!(s1.b, 0); + let s2 = s0.g(); + assert_eq!(s2.a, 0); + assert_eq!(s2.b, 1); +} diff --git a/src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs b/src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs new file mode 100644 index 00000000000..323705f3f95 --- /dev/null +++ b/src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs @@ -0,0 +1,21 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This tests reification from safe function to `unsafe fn` pointer + +fn do_nothing() -> () {} + +unsafe fn call_unsafe(func: unsafe fn() -> ()) -> () { + func() +} + +pub fn main() { + unsafe { call_unsafe(do_nothing); } +} diff --git a/src/test/run-pass/uniq-self-in-mut-slot.rs b/src/test/run-pass/uniq-self-in-mut-slot.rs index baca157a488..7910380abee 100644 --- a/src/test/run-pass/uniq-self-in-mut-slot.rs +++ b/src/test/run-pass/uniq-self-in-mut-slot.rs @@ -17,7 +17,7 @@ struct X { } trait Changer { - fn change(mut self: Box<Self>) -> Box<Self>; + fn change(self: Box<Self>) -> Box<Self>; } impl Changer for X { diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs index 978e991d508..800186a926d 100644 --- a/src/tools/cargotest/main.rs +++ b/src/tools/cargotest/main.rs @@ -24,7 +24,7 @@ struct Test { const TEST_REPOS: &'static [Test] = &[Test { name: "cargo", repo: "https://github.com/rust-lang/cargo", - sha: "d3bad1ab29efae414e9b4c24534b2d02b3a59782", + sha: "806e3c368a15f618244a3b4e918bf77f9c403fd0", lock: None, }, Test { diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs index ea274266f1a..ef93b0858b0 100644 --- a/src/tools/tidy/src/bins.rs +++ b/src/tools/tidy/src/bins.rs @@ -44,28 +44,27 @@ pub fn check(path: &Path, bad: &mut bool) { let filename = file.file_name().unwrap().to_string_lossy(); let extensions = [".py", ".sh"]; if extensions.iter().any(|e| filename.ends_with(e)) { - return + return; } let metadata = t!(fs::symlink_metadata(&file), &file); if metadata.mode() & 0o111 != 0 { let rel_path = file.strip_prefix(path).unwrap(); let git_friendly_path = rel_path.to_str().unwrap().replace("\\", "/"); - let ret_code = Command::new("git") - .arg("ls-files") - .arg(&git_friendly_path) - .current_dir(path) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status() - .unwrap_or_else(|e| { - panic!("could not run git ls-files: {}", e); - }); - if ret_code.success() { + let output = Command::new("git") + .arg("ls-files") + .arg(&git_friendly_path) + .current_dir(path) + .stderr(Stdio::null()) + .output() + .unwrap_or_else(|e| { + panic!("could not run git ls-files: {}", e); + }); + let path_bytes = rel_path.as_os_str().as_bytes(); + if output.status.success() && output.stdout.starts_with(path_bytes) { println!("binary checked into source: {}", file.display()); *bad = true; } } }) } - diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 199e8a77df7..4ef07f7e4b8 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -18,27 +18,42 @@ //! * Library features have at most one `since` value use std::collections::HashMap; +use std::fmt; use std::fs::File; use std::io::prelude::*; use std::path::Path; -const STATUSES: &'static [&'static str] = &[ - "Active", "Deprecated", "Removed", "Accepted", -]; +#[derive(PartialEq)] +enum Status { + Stable, + Unstable, +} + +impl fmt::Display for Status { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let as_str = match *self { + Status::Stable => "stable", + Status::Unstable => "unstable", + }; + fmt::Display::fmt(as_str, f) + } +} + struct Feature { name: String, + level: Status, since: String, - status: String, } struct LibFeature { - level: String, + level: Status, since: String, } pub fn check(path: &Path, bad: &mut bool) { let features = collect_lang_features(&path.join("libsyntax/feature_gate.rs")); + assert!(!features.is_empty()); let mut lib_features = HashMap::<String, LibFeature>::new(); let mut contents = String::new(); @@ -48,7 +63,7 @@ pub fn check(path: &Path, bad: &mut bool) { let filename = file.file_name().unwrap().to_string_lossy(); if !filename.ends_with(".rs") || filename == "features.rs" || filename == "diagnostic_list.rs" { - return + return; } contents.truncate(0); @@ -60,24 +75,24 @@ pub fn check(path: &Path, bad: &mut bool) { *bad = true; }; let level = if line.contains("[unstable(") { - "unstable" + Status::Unstable } else if line.contains("[stable(") { - "stable" + Status::Stable } else { - continue + continue; }; let feature_name = match find_attr_val(line, "feature") { Some(name) => name, None => { err("malformed stability attribute"); - continue + continue; } }; let since = match find_attr_val(line, "since") { Some(name) => name, - None if level == "stable" => { + None if level == Status::Stable => { err("malformed stability attribute"); - continue + continue; } None => "None", }; @@ -92,27 +107,34 @@ pub fn check(path: &Path, bad: &mut bool) { if s.since != since { err("different `since` than before"); } - continue + continue; } - lib_features.insert(feature_name.to_owned(), LibFeature { - level: level.to_owned(), - since: since.to_owned(), - }); + lib_features.insert(feature_name.to_owned(), + LibFeature { + level: level, + since: since.to_owned(), + }); } }); if *bad { - return + return; } let mut lines = Vec::new(); for feature in features { lines.push(format!("{:<32} {:<8} {:<12} {:<8}", - feature.name, "lang", feature.status, feature.since)); + feature.name, + "lang", + feature.level, + feature.since)); } for (name, feature) in lib_features { lines.push(format!("{:<32} {:<8} {:<12} {:<8}", - name, "lib", feature.level, feature.since)); + name, + "lib", + feature.level, + feature.since)); } lines.sort(); @@ -122,39 +144,32 @@ pub fn check(path: &Path, bad: &mut bool) { } fn find_attr_val<'a>(line: &'a str, attr: &str) -> Option<&'a str> { - line.find(attr).and_then(|i| { - line[i..].find("\"").map(|j| i + j + 1) - }).and_then(|i| { - line[i..].find("\"").map(|j| (i, i + j)) - }).map(|(i, j)| { - &line[i..j] - }) + line.find(attr) + .and_then(|i| line[i..].find('"').map(|j| i + j + 1)) + .and_then(|i| line[i..].find('"').map(|j| (i, i + j))) + .map(|(i, j)| &line[i..j]) } fn collect_lang_features(path: &Path) -> Vec<Feature> { let mut contents = String::new(); t!(t!(File::open(path)).read_to_string(&mut contents)); - let mut features = Vec::new(); - for line in contents.lines().map(|l| l.trim()) { - if !STATUSES.iter().any(|s| line.starts_with(&format!("({}", s))) { - continue - } - let mut parts = line.split(","); - let status = match &parts.next().unwrap().trim().replace("(", "")[..] { - "active" => "unstable", - "removed" => "unstable", - "accepted" => "stable", - s => panic!("unknown status: {}", s), - }; - let name = parts.next().unwrap().trim().to_owned(); - let since = parts.next().unwrap().trim().replace("\"", ""); - - features.push(Feature { - name: name, - since: since, - status: status.to_owned(), - }); - } - return features + contents.lines() + .filter_map(|line| { + let mut parts = line.trim().split(","); + let level = match parts.next().map(|l| l.trim().trim_left_matches('(')) { + Some("active") => Status::Unstable, + Some("removed") => Status::Unstable, + Some("accepted") => Status::Stable, + _ => return None, + }; + let name = parts.next().unwrap().trim(); + let since = parts.next().unwrap().trim().trim_matches('"'); + Some(Feature { + name: name.to_owned(), + level: level, + since: since.to_owned(), + }) + }) + .collect() } |
