diff --git a/src/Cargo.lock b/src/Cargo.lock index b34007db8ac7a..a9a6fabb5b23c 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -27,7 +27,7 @@ version = "0.0.0" dependencies = [ "build_helper 0.1.0", "core 0.0.0", - "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.0.0", ] @@ -48,6 +48,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "arena" version = "0.0.0" +[[package]] +name = "atty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bitflags" version = "0.5.0" @@ -55,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitflags" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -65,11 +75,11 @@ dependencies = [ "build_helper 0.1.0", "cmake 0.1.21 (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.43 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.21 (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.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -77,7 +87,7 @@ dependencies = [ name = "build-manifest" version = "0.1.0" dependencies = [ - "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -94,17 +104,17 @@ version = "0.1.0" [[package]] name = "clap" -version = "2.20.5" +version = "2.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -112,7 +122,7 @@ name = "cmake" version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -130,7 +140,7 @@ version = "0.0.0" dependencies = [ "build_helper 0.1.0", "core 0.0.0", - "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -140,7 +150,7 @@ dependencies = [ "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -186,7 +196,7 @@ name = "flate" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -195,7 +205,7 @@ version = "0.0.0" [[package]] name = "gcc" -version = "0.3.43" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -221,7 +231,7 @@ dependencies = [ "pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -274,7 +284,7 @@ name = "mdbook" version = "0.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.21.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "handlebars 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -397,11 +407,28 @@ name = "regex-syntax" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rls-data" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rls-span 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rls-span" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustbook" version = "0.1.0" dependencies = [ - "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.21.1 (registry+https://github.com/rust-lang/crates.io-index)", "mdbook 0.0.18 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -435,7 +462,7 @@ dependencies = [ [[package]] name = "rustc-serialize" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -577,7 +604,7 @@ name = "rustc_llvm" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_bitflags 0.0.0", ] @@ -690,8 +717,10 @@ name = "rustc_save_analysis" version = "0.0.0" dependencies = [ "log 0.0.0", + "rls-data 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-span 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", - "serialize 0.0.0", + "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", "syntax 0.0.0", "syntax_pos 0.0.0", ] @@ -751,7 +780,7 @@ version = "0.0.0" dependencies = [ "arena 0.0.0", "build_helper 0.1.0", - "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.0.0", "rustc 0.0.0", "rustc_back 0.0.0", @@ -799,7 +828,7 @@ dependencies = [ "collections 0.0.0", "compiler_builtins 0.0.0", "core 0.0.0", - "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.0.0", "panic_abort 0.0.0", "panic_unwind 0.0.0", @@ -904,7 +933,7 @@ name = "toml" version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -940,7 +969,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "vec_map" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -961,15 +990,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2" "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" +"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159" "checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23" -"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" -"checksum clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758" +"checksum bitflags 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e1ab483fc81a8143faa7203c4a3c02888ebd1a782e37e41fa34753ba9a162" +"checksum clap 2.21.1 (registry+https://github.com/rust-lang/crates.io-index)" = "74a80f603221c9cd9aa27a28f52af452850051598537bb6b359c38a7d61e5cda" "checksum cmake 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "e1acc68a3f714627af38f9f5d09706a28584ba60dfe2cca68f40bf779f941b25" "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" "checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f" "checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83" "checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922" -"checksum gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "c07c758b972368e703a562686adb39125707cc1ef3399da8c019fc6c2498a75d" +"checksum gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)" = "a32cd40070d7611ab76343dcb3204b2bb28c8a9450989a83a3d590248142f439" "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685" "checksum handlebars 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b2249f6f0dc5a3bb2b3b1a8f797dfccbc4b053344d773d654ad565e51427d335" "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c" @@ -987,7 +1017,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0aad603e8d7fb67da22dbdf1f4b826ce8829e406124109e73cf1b2454b93a71c" "checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01" "checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457" -"checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b" +"checksum rls-data 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af1dfff00189fd7b78edb9af131b0de703676c04fa8126aed77fd2c586775a4d" +"checksum rls-span 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8656f7b850ac85fb204ef94318c641bbb15a32766e12f9a589a23e4c0fbc38db" +"checksum rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "684ce48436d6465300c9ea783b6b14c4361d6b8dcbb1375b486a69cc19e2dfb0" "checksum serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a702319c807c016e51f672e5c77d6f0b46afddd744b5e437d6b8436b888b458f" "checksum serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc45439552eb8fb86907a2c41c1fd0ef97458efb87ff7f878db466eb581824e" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" @@ -1000,7 +1032,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" -"checksum vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac5efe5cb0fa14ec2f84f83c701c562ee63f6dcc680861b21d65c682adfb05f" +"checksum vec_map 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8cdc8b93bd0198ed872357fb2e667f7125646b1762f16d60b2c96350d361897" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "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/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index ba85e81ff4fc4..62b7f6cb72e3b 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -94,6 +94,13 @@ fn main() { cmd.arg("-Cprefer-dynamic"); } + // Pass the `rustbuild` feature flag to crates which rustbuild is + // building. See the comment in bootstrap/lib.rs where this env var is + // set for more details. + if env::var_os("RUSTBUILD_UNSTABLE").is_some() { + cmd.arg("--cfg").arg("rustbuild"); + } + // Help the libc crate compile by assisting it in finding the MUSL // native libraries. if let Some(s) = env::var_os("MUSL_ROOT") { diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 270cb8490d9a7..26f3c06306197 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -180,7 +180,7 @@ struct Crate { /// /// These entries currently correspond to the various output directories of the /// build system, with each mod generating output in a different directory. -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq, Eq)] pub enum Mode { /// This cargo is going to build the standard library, placing output in the /// "stageN-std" directory. @@ -491,7 +491,7 @@ impl Build { // For other crates, however, we know that we've already got a standard // library up and running, so we can use the normal compiler to compile // build scripts in that situation. - if let Mode::Libstd = mode { + if mode == Mode::Libstd { cargo.env("RUSTC_SNAPSHOT", &self.rustc) .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir()); } else { @@ -499,6 +499,27 @@ impl Build { .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_libdir(compiler)); } + // There are two invariants we try must maintain: + // * stable crates cannot depend on unstable crates (general Rust rule), + // * crates that end up in the sysroot must be unstable (rustbuild rule). + // + // In order to do enforce the latter, we pass the env var + // `RUSTBUILD_UNSTABLE` down the line for any crates which will end up + // in the sysroot. We read this in bootstrap/bin/rustc.rs and if it is + // set, then we pass the `rustbuild` feature to rustc when building the + // the crate. + // + // In turn, crates that can be used here should recognise the `rustbuild` + // feature and opt-in to `rustc_private`. + // + // We can't always pass `rustbuild` because crates which are outside of + // the comipiler, libs, and tests are stable and we don't want to make + // their deps unstable (since this would break the first invariant + // above). + if mode != Mode::Tool { + cargo.env("RUSTBUILD_UNSTABLE", "1"); + } + // Ignore incremental modes except for stage0, since we're // not guaranteeing correctness acros builds if the compiler // is changing under your feet.` diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs index 1ec1749c3aa64..62a8816462191 100644 --- a/src/libcollections/fmt.rs +++ b/src/libcollections/fmt.rs @@ -367,6 +367,10 @@ //! like `{:08}` would yield `00000001` for the integer `1`, while the //! same format would yield `-0000001` for the integer `-1`. Notice that //! the negative version has one fewer zero than the positive version. +//! Note that padding zeroes are always placed after the sign (if any) +//! and before the digits. When used together with the `#` flag, a similar +//! rule applies: padding zeroes are inserted after the prefix but before +//! the digits. //! //! ## Width //! diff --git a/src/libcompiler_builtins/lib.rs b/src/libcompiler_builtins/lib.rs index fb42b915c7694..58aba11e4394f 100644 --- a/src/libcompiler_builtins/lib.rs +++ b/src/libcompiler_builtins/lib.rs @@ -34,8 +34,8 @@ pub mod reimpls { macro_rules! ashl { ($a:expr, $b:expr, $ty:ty) => {{ let (a, b) = ($a, $b); - let bits = (::core::mem::size_of::<$ty>() * 8) as $ty; - let half_bits = bits >> 1; + let bits = ::core::mem::size_of::<$ty>().wrapping_mul(8) as $ty; + let half_bits = bits.wrapping_shr(1); if b & half_bits != 0 { <$ty>::from_parts(0, a.low().wrapping_shl( b.wrapping_sub(half_bits) as u32)) @@ -58,8 +58,8 @@ pub mod reimpls { macro_rules! ashr { ($a: expr, $b: expr, $ty:ty) => {{ let (a, b) = ($a, $b); - let bits = (::core::mem::size_of::<$ty>() * 8) as $ty; - let half_bits = bits >> 1; + let bits = ::core::mem::size_of::<$ty>().wrapping_mul(8) as $ty; + let half_bits = bits.wrapping_shr(1); if b & half_bits != 0 { <$ty>::from_parts(a.high().wrapping_shr(b.wrapping_sub(half_bits) as u32) as <$ty as LargeInt>::LowHalf, @@ -83,8 +83,8 @@ pub mod reimpls { macro_rules! lshr { ($a: expr, $b: expr, $ty:ty) => {{ let (a, b) = ($a, $b); - let bits = (::core::mem::size_of::<$ty>() * 8) as $ty; - let half_bits = bits >> 1; + let bits = ::core::mem::size_of::<$ty>().wrapping_mul(8) as $ty; + let half_bits = bits.wrapping_shr(1); if b & half_bits != 0 { <$ty>::from_parts(a.high().wrapping_shr(b.wrapping_sub(half_bits) as u32), 0) } else if b == 0 { @@ -370,7 +370,7 @@ pub mod reimpls { macro_rules! mul { ($a:expr, $b:expr, $ty: ty, $tyh: ty) => {{ let (a, b) = ($a, $b); - let half_bits = ((::core::mem::size_of::<$tyh>() * 8) / 2) as u32; + let half_bits = ::core::mem::size_of::<$tyh>().wrapping_mul(4) as u32; let lower_mask = (!0u64).wrapping_shr(half_bits); let mut low = (a.low() & lower_mask).wrapping_mul(b.low() & lower_mask); let mut t = low.wrapping_shr(half_bits); @@ -478,7 +478,7 @@ pub mod reimpls { let mantissa_fraction = repr & <$fromty as FloatStuff>::MANTISSA_MASK; let mantissa = mantissa_fraction | <$fromty as FloatStuff>::MANTISSA_LEAD_BIT; if sign == -1.0 || exponent < 0 { return 0 as u128; } - if exponent > ::core::mem::size_of::<$outty>() as i32 * 8 { + if exponent > ::core::mem::size_of::<$outty>().wrapping_mul(8) as i32 { return !(0 as u128); } (if exponent < (<$fromty as FloatStuff>::MANTISSA_BITS) as i32 { @@ -503,7 +503,7 @@ pub mod reimpls { let mantissa = mantissa_fraction | <$fromty as FloatStuff>::MANTISSA_LEAD_BIT; if exponent < 0 { return 0 as i128; } - if exponent > ::core::mem::size_of::<$outty>() as i32 * 8 { + if exponent > ::core::mem::size_of::<$outty>().wrapping_mul(8) as i32 { let ret = if sign > 0.0 { <$outty>::max_value() } else { <$outty>::min_value() }; return ret } diff --git a/src/libcore/char.rs b/src/libcore/char.rs index a9282b5b02fea..649fdf394e422 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -209,10 +209,10 @@ impl From for char { #[unstable(feature = "try_from", issue = "33417")] impl TryFrom for char { - type Err = CharTryFromError; + type Error = CharTryFromError; #[inline] - fn try_from(i: u32) -> Result { + fn try_from(i: u32) -> Result { if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) { Err(CharTryFromError(())) } else { diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 70e285f202e52..0b0f831f093b0 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -48,6 +48,8 @@ #![stable(feature = "rust1", since = "1.0.0")] +use str::FromStr; + /// A cheap, reference-to-reference conversion. /// /// `AsRef` is very similar to, but different than, [`Borrow`]. See @@ -212,20 +214,20 @@ pub trait From: Sized { #[unstable(feature = "try_from", issue = "33417")] pub trait TryInto: Sized { /// The type returned in the event of a conversion error. - type Err; + type Error; /// Performs the conversion. - fn try_into(self) -> Result; + fn try_into(self) -> Result; } /// Attempt to construct `Self` via a conversion. #[unstable(feature = "try_from", issue = "33417")] pub trait TryFrom: Sized { /// The type returned in the event of a conversion error. - type Err; + type Error; /// Performs the conversion. - fn try_from(value: T) -> Result; + fn try_from(value: T) -> Result; } //////////////////////////////////////////////////////////////////////////////// @@ -290,9 +292,9 @@ impl From for T { // TryFrom implies TryInto #[unstable(feature = "try_from", issue = "33417")] impl TryInto for T where U: TryFrom { - type Err = U::Err; + type Error = U::Error; - fn try_into(self) -> Result { + fn try_into(self) -> Result { U::try_from(self) } } @@ -322,3 +324,13 @@ impl AsRef for str { self } } + +// FromStr implies TryFrom<&str> +#[unstable(feature = "try_from", issue = "33417")] +impl<'a, T> TryFrom<&'a str> for T where T: FromStr { + type Error = ::Err; + + fn try_from(s: &'a str) -> Result { + FromStr::from_str(s) + } +} diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 1657342ff6ac6..0bfab92fa5d51 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1045,6 +1045,7 @@ impl<'a> Formatter<'a> { // is zero Some(min) if self.sign_aware_zero_pad() => { self.fill = '0'; + self.align = rt::v1::Alignment::Right; write_prefix(self)?; self.with_padding(min - width, rt::v1::Alignment::Right, |f| { f.buf.write_str(buf) @@ -1153,8 +1154,9 @@ impl<'a> Formatter<'a> { // for the sign-aware zero padding, we render the sign first and // behave as if we had no sign from the beginning. let mut formatted = formatted.clone(); - let mut align = self.align; let old_fill = self.fill; + let old_align = self.align; + let mut align = old_align; if self.sign_aware_zero_pad() { // a sign always goes first let sign = unsafe { str::from_utf8_unchecked(formatted.sign) }; @@ -1165,6 +1167,7 @@ impl<'a> Formatter<'a> { width = if width < sign.len() { 0 } else { width - sign.len() }; align = rt::v1::Alignment::Right; self.fill = '0'; + self.align = rt::v1::Alignment::Right; } // remaining parts go through the ordinary padding process. @@ -1177,6 +1180,7 @@ impl<'a> Formatter<'a> { }) }; self.fill = old_fill; + self.align = old_align; ret } else { // this is the common case and we take a shortcut diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 12410c08f399b..f8d067e9696fd 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1238,6 +1238,15 @@ extern "rust-intrinsic" { /// undefined behavior where y = 0 or x = `T::min_value()` and y = -1 pub fn unchecked_rem(x: T, y: T) -> T; + /// Performs an unchecked left shift, resulting in undefined behavior when + /// y < 0 or y >= N, where N is the width of T in bits. + #[cfg(not(stage0))] + pub fn unchecked_shl(x: T, y: T) -> T; + /// Performs an unchecked right shift, resulting in undefined behavior when + /// y < 0 or y >= N, where N is the width of T in bits. + #[cfg(not(stage0))] + pub fn unchecked_shr(x: T, y: T) -> T; + /// Returns (a + b) mod 2^N, where N is the width of T in bits. /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `wrapping_add` method. For example, diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 81c80ba51152d..ccfe6364e6af6 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -177,7 +177,7 @@ macro_rules! checked_op { // `Int` + `SignedInt` implemented for signed integers macro_rules! int_impl { - ($ActualT:ident, $UnsignedT:ty, $BITS:expr, + ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr, $add_with_overflow:path, $sub_with_overflow:path, $mul_with_overflow:path) => { @@ -850,6 +850,17 @@ macro_rules! int_impl { /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] + #[cfg(not(stage0))] + pub fn wrapping_shl(self, rhs: u32) -> Self { + unsafe { + intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT) + } + } + + /// Stage 0 + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline(always)] + #[cfg(stage0)] pub fn wrapping_shl(self, rhs: u32) -> Self { self.overflowing_shl(rhs).0 } @@ -875,6 +886,17 @@ macro_rules! int_impl { /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] + #[cfg(not(stage0))] + pub fn wrapping_shr(self, rhs: u32) -> Self { + unsafe { + intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT) + } + } + + /// Stage 0 + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline(always)] + #[cfg(stage0)] pub fn wrapping_shr(self, rhs: u32) -> Self { self.overflowing_shr(rhs).0 } @@ -1089,6 +1111,15 @@ macro_rules! int_impl { /// ``` #[inline] #[stable(feature = "wrapping", since = "1.7.0")] + #[cfg(not(stage0))] + pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { + (self.wrapping_shl(rhs), (rhs > ($BITS - 1))) + } + + /// Stage 0 + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + #[cfg(stage0)] pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { (self << (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) } @@ -1111,6 +1142,15 @@ macro_rules! int_impl { /// ``` #[inline] #[stable(feature = "wrapping", since = "1.7.0")] + #[cfg(not(stage0))] + pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { + (self.wrapping_shr(rhs), (rhs > ($BITS - 1))) + } + + /// Stage 0 + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + #[cfg(stage0)] pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { (self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) } @@ -1268,7 +1308,7 @@ macro_rules! int_impl { #[lang = "i8"] impl i8 { - int_impl! { i8, u8, 8, + int_impl! { i8, i8, u8, 8, intrinsics::add_with_overflow, intrinsics::sub_with_overflow, intrinsics::mul_with_overflow } @@ -1276,7 +1316,7 @@ impl i8 { #[lang = "i16"] impl i16 { - int_impl! { i16, u16, 16, + int_impl! { i16, i16, u16, 16, intrinsics::add_with_overflow, intrinsics::sub_with_overflow, intrinsics::mul_with_overflow } @@ -1284,7 +1324,7 @@ impl i16 { #[lang = "i32"] impl i32 { - int_impl! { i32, u32, 32, + int_impl! { i32, i32, u32, 32, intrinsics::add_with_overflow, intrinsics::sub_with_overflow, intrinsics::mul_with_overflow } @@ -1292,7 +1332,7 @@ impl i32 { #[lang = "i64"] impl i64 { - int_impl! { i64, u64, 64, + int_impl! { i64, i64, u64, 64, intrinsics::add_with_overflow, intrinsics::sub_with_overflow, intrinsics::mul_with_overflow } @@ -1300,7 +1340,7 @@ impl i64 { #[lang = "i128"] impl i128 { - int_impl! { i128, u128, 128, + int_impl! { i128, i128, u128, 128, intrinsics::add_with_overflow, intrinsics::sub_with_overflow, intrinsics::mul_with_overflow } @@ -1309,7 +1349,7 @@ impl i128 { #[cfg(target_pointer_width = "16")] #[lang = "isize"] impl isize { - int_impl! { i16, u16, 16, + int_impl! { isize, i16, u16, 16, intrinsics::add_with_overflow, intrinsics::sub_with_overflow, intrinsics::mul_with_overflow } @@ -1318,7 +1358,7 @@ impl isize { #[cfg(target_pointer_width = "32")] #[lang = "isize"] impl isize { - int_impl! { i32, u32, 32, + int_impl! { isize, i32, u32, 32, intrinsics::add_with_overflow, intrinsics::sub_with_overflow, intrinsics::mul_with_overflow } @@ -1327,7 +1367,7 @@ impl isize { #[cfg(target_pointer_width = "64")] #[lang = "isize"] impl isize { - int_impl! { i64, u64, 64, + int_impl! { isize, i64, u64, 64, intrinsics::add_with_overflow, intrinsics::sub_with_overflow, intrinsics::mul_with_overflow } @@ -1335,7 +1375,7 @@ impl isize { // `Int` + `UnsignedInt` implemented for unsigned integers macro_rules! uint_impl { - ($ActualT:ty, $BITS:expr, + ($SelfT:ty, $ActualT:ty, $BITS:expr, $ctpop:path, $ctlz:path, $cttz:path, @@ -1978,6 +2018,17 @@ macro_rules! uint_impl { /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] + #[cfg(not(stage0))] + pub fn wrapping_shl(self, rhs: u32) -> Self { + unsafe { + intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT) + } + } + + /// Stage 0 + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline(always)] + #[cfg(stage0)] pub fn wrapping_shl(self, rhs: u32) -> Self { self.overflowing_shl(rhs).0 } @@ -2003,6 +2054,17 @@ macro_rules! uint_impl { /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] + #[cfg(not(stage0))] + pub fn wrapping_shr(self, rhs: u32) -> Self { + unsafe { + intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT) + } + } + + /// Stage 0 + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline(always)] + #[cfg(stage0)] pub fn wrapping_shr(self, rhs: u32) -> Self { self.overflowing_shr(rhs).0 } @@ -2170,6 +2232,15 @@ macro_rules! uint_impl { /// ``` #[inline] #[stable(feature = "wrapping", since = "1.7.0")] + #[cfg(not(stage0))] + pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { + (self.wrapping_shl(rhs), (rhs > ($BITS - 1))) + } + + /// Stage 0 + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + #[cfg(stage0)] pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { (self << (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) } @@ -2192,6 +2263,16 @@ macro_rules! uint_impl { /// ``` #[inline] #[stable(feature = "wrapping", since = "1.7.0")] + #[cfg(not(stage0))] + pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { + (self.wrapping_shr(rhs), (rhs > ($BITS - 1))) + + } + + /// Stage 0 + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + #[cfg(stage0)] pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { (self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) } @@ -2292,7 +2373,7 @@ macro_rules! uint_impl { #[lang = "u8"] impl u8 { - uint_impl! { u8, 8, + uint_impl! { u8, u8, 8, intrinsics::ctpop, intrinsics::ctlz, intrinsics::cttz, @@ -2304,7 +2385,7 @@ impl u8 { #[lang = "u16"] impl u16 { - uint_impl! { u16, 16, + uint_impl! { u16, u16, 16, intrinsics::ctpop, intrinsics::ctlz, intrinsics::cttz, @@ -2316,7 +2397,7 @@ impl u16 { #[lang = "u32"] impl u32 { - uint_impl! { u32, 32, + uint_impl! { u32, u32, 32, intrinsics::ctpop, intrinsics::ctlz, intrinsics::cttz, @@ -2328,7 +2409,7 @@ impl u32 { #[lang = "u64"] impl u64 { - uint_impl! { u64, 64, + uint_impl! { u64, u64, 64, intrinsics::ctpop, intrinsics::ctlz, intrinsics::cttz, @@ -2340,7 +2421,7 @@ impl u64 { #[lang = "u128"] impl u128 { - uint_impl! { u128, 128, + uint_impl! { u128, u128, 128, intrinsics::ctpop, intrinsics::ctlz, intrinsics::cttz, @@ -2353,7 +2434,7 @@ impl u128 { #[cfg(target_pointer_width = "16")] #[lang = "usize"] impl usize { - uint_impl! { u16, 16, + uint_impl! { usize, u16, 16, intrinsics::ctpop, intrinsics::ctlz, intrinsics::cttz, @@ -2365,7 +2446,7 @@ impl usize { #[cfg(target_pointer_width = "32")] #[lang = "usize"] impl usize { - uint_impl! { u32, 32, + uint_impl! { usize, u32, 32, intrinsics::ctpop, intrinsics::ctlz, intrinsics::cttz, @@ -2378,7 +2459,7 @@ impl usize { #[cfg(target_pointer_width = "64")] #[lang = "usize"] impl usize { - uint_impl! { u64, 64, + uint_impl! { usize, u64, 64, intrinsics::ctpop, intrinsics::ctlz, intrinsics::cttz, @@ -2591,7 +2672,7 @@ macro_rules! same_sign_try_from_int_impl { ($storage:ty, $target:ty, $($source:ty),*) => {$( #[unstable(feature = "try_from", issue = "33417")] impl TryFrom<$source> for $target { - type Err = TryFromIntError; + type Error = TryFromIntError; fn try_from(u: $source) -> Result<$target, TryFromIntError> { let min = <$target as FromStrRadixHelper>::min_value() as $storage; @@ -2623,7 +2704,7 @@ macro_rules! cross_sign_from_int_impl { ($unsigned:ty, $($signed:ty),*) => {$( #[unstable(feature = "try_from", issue = "33417")] impl TryFrom<$unsigned> for $signed { - type Err = TryFromIntError; + type Error = TryFromIntError; fn try_from(u: $unsigned) -> Result<$signed, TryFromIntError> { let max = <$signed as FromStrRadixHelper>::max_value() as u128; @@ -2637,7 +2718,7 @@ macro_rules! cross_sign_from_int_impl { #[unstable(feature = "try_from", issue = "33417")] impl TryFrom<$signed> for $unsigned { - type Err = TryFromIntError; + type Error = TryFromIntError; fn try_from(u: $signed) -> Result<$unsigned, TryFromIntError> { let max = <$unsigned as FromStrRadixHelper>::max_value() as u128; diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 0775142651006..cf3e8a684dfab 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -18,6 +18,7 @@ use self::pattern::Pattern; use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher}; use char; +use convert::TryFrom; use fmt; use iter::{Map, Cloned, FusedIterator}; use mem; @@ -1782,7 +1783,7 @@ pub trait StrExt { #[stable(feature = "core", since = "1.6.0")] fn is_empty(&self) -> bool; #[stable(feature = "core", since = "1.6.0")] - fn parse(&self) -> Result; + fn parse<'a, T: TryFrom<&'a str>>(&'a self) -> Result; } // truncate `&str` to length at most equal to `max` @@ -2081,7 +2082,9 @@ impl StrExt for str { fn is_empty(&self) -> bool { self.len() == 0 } #[inline] - fn parse(&self) -> Result { FromStr::from_str(self) } + fn parse<'a, T>(&'a self) -> Result where T: TryFrom<&'a str> { + T::try_from(self) + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libproc_macro_plugin/lib.rs b/src/libproc_macro_plugin/lib.rs index e904290957619..a6dad64125331 100644 --- a/src/libproc_macro_plugin/lib.rs +++ b/src/libproc_macro_plugin/lib.rs @@ -13,62 +13,64 @@ //! A library for procedural macro writers. //! //! ## Usage -//! This crate provides the `qquote!` macro for syntax creation. +//! This crate provides the `quote!` macro for syntax creation. //! -//! The `qquote!` macro uses the crate `syntax`, so users must declare `extern crate syntax;` +//! The `quote!` macro uses the crate `syntax`, so users must declare `extern crate syntax;` //! at the crate root. This is a temporary solution until we have better hygiene. //! //! ## Quasiquotation //! //! The quasiquoter creates output that, when run, constructs the tokenstream specified as -//! input. For example, `qquote!(5 + 5)` will produce a program, that, when run, will +//! input. For example, `quote!(5 + 5)` will produce a program, that, when run, will //! construct the TokenStream `5 | + | 5`. //! //! ### Unquoting //! -//! Unquoting is currently done as `unquote`, and works by taking the single next -//! TokenTree in the TokenStream as the unquoted term. Ergonomically, `unquote(foo)` works -//! fine, but `unquote foo` is also supported. +//! Unquoting is done with `$`, and works by taking the single next ident as the unquoted term. +//! To quote `$` itself, use `$$`. //! -//! A simple example might be: +//! A simple example is: //! //!``` //!fn double(tmp: TokenStream) -> TokenStream { -//! qquote!(unquote(tmp) * 2) +//! quote!($tmp * 2) //!} //!``` //! -//! ### Large Example: Implementing Scheme's `cond` +//! ### Large example: Scheme's `cond` //! -//! Below is the full implementation of Scheme's `cond` operator. +//! Below is an example implementation of Scheme's `cond`. //! //! ``` -//! fn cond_rec(input: TokenStream) -> TokenStream { -//! if input.is_empty() { return quote!(); } -//! -//! let next = input.slice(0..1); -//! let rest = input.slice_from(1..); -//! -//! let clause : TokenStream = match next.maybe_delimited() { -//! Some(ts) => ts, -//! _ => panic!("Invalid input"), -//! }; -//! -//! // clause is ([test]) [rhs] -//! if clause.len() < 2 { panic!("Invalid macro usage in cond: {:?}", clause) } -//! -//! let test: TokenStream = clause.slice(0..1); -//! let rhs: TokenStream = clause.slice_from(1..); -//! -//! if ident_eq(&test[0], str_to_ident("else")) || rest.is_empty() { -//! quote!({unquote(rhs)}) -//! } else { -//! quote!({if unquote(test) { unquote(rhs) } else { cond!(unquote(rest)) } }) -//! } +//! fn cond(input: TokenStream) -> TokenStream { +//! let mut conds = Vec::new(); +//! let mut input = input.trees().peekable(); +//! while let Some(tree) = input.next() { +//! let mut cond = match tree { +//! TokenTree::Delimited(_, ref delimited) => delimited.stream(), +//! _ => panic!("Invalid input"), +//! }; +//! let mut trees = cond.trees(); +//! let test = trees.next(); +//! let rhs = trees.collect::(); +//! if rhs.is_empty() { +//! panic!("Invalid macro usage in cond: {}", cond); +//! } +//! let is_else = match test { +//! Some(TokenTree::Token(_, Token::Ident(ident))) if ident.name == "else" => true, +//! _ => false, +//! }; +//! conds.push(if is_else || input.peek().is_none() { +//! quote!({ $rhs }) +//! } else { +//! let test = test.unwrap(); +//! quote!(if $test { $rhs } else) +//! }); +//! } +//! +//! conds.into_iter().collect() //! } //! ``` -//! - #![crate_name = "proc_macro_plugin"] #![unstable(feature = "rustc_private", issue = "27812")] #![feature(plugin_registrar)] @@ -87,8 +89,8 @@ extern crate rustc_plugin; extern crate syntax; extern crate syntax_pos; -mod qquote; -use qquote::qquote; +mod quote; +use quote::quote; use rustc_plugin::Registry; use syntax::ext::base::SyntaxExtension; @@ -99,6 +101,6 @@ use syntax::symbol::Symbol; #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_syntax_extension(Symbol::intern("qquote"), - SyntaxExtension::ProcMacro(Box::new(qquote))); + reg.register_syntax_extension(Symbol::intern("quote"), + SyntaxExtension::ProcMacro(Box::new(quote))); } diff --git a/src/libproc_macro_plugin/qquote.rs b/src/libproc_macro_plugin/quote.rs similarity index 86% rename from src/libproc_macro_plugin/qquote.rs rename to src/libproc_macro_plugin/quote.rs index 0276587ed52b1..ad71584b61a0f 100644 --- a/src/libproc_macro_plugin/qquote.rs +++ b/src/libproc_macro_plugin/quote.rs @@ -19,7 +19,7 @@ use syntax_pos::DUMMY_SP; use std::iter; -pub fn qquote<'cx>(stream: TokenStream) -> TokenStream { +pub fn quote<'cx>(stream: TokenStream) -> TokenStream { stream.quote() } @@ -72,28 +72,32 @@ impl Quote for TokenStream { return quote!(::syntax::tokenstream::TokenStream::empty()); } - struct Quote(iter::Peekable); + struct Quoter(iter::Peekable); - impl Iterator for Quote { + impl Iterator for Quoter { type Item = TokenStream; fn next(&mut self) -> Option { - let is_unquote = match self.0.peek() { - Some(&TokenTree::Token(_, Token::Ident(ident))) if ident.name == "unquote" => { - self.0.next(); - true + let quoted_tree = if let Some(&TokenTree::Token(_, Token::Dollar)) = self.0.peek() { + self.0.next(); + match self.0.next() { + Some(tree @ TokenTree::Token(_, Token::Ident(..))) => Some(tree.into()), + Some(tree @ TokenTree::Token(_, Token::Dollar)) => Some(tree.quote()), + // FIXME(jseyfried): improve these diagnostics + Some(..) => panic!("`$` must be followed by an ident or `$` in `quote!`"), + None => panic!("unexpected trailing `$` in `quote!`"), } - _ => false, + } else { + self.0.next().as_ref().map(Quote::quote) }; - self.0.next().map(|tree| { - let quoted_tree = if is_unquote { tree.into() } else { tree.quote() }; + quoted_tree.map(|quoted_tree| { quote!(::syntax::tokenstream::TokenStream::from((unquote quoted_tree)),) }) } } - let quoted = Quote(self.trees().peekable()).collect::(); + let quoted = Quoter(self.trees().peekable()).collect::(); quote!([(unquote quoted)].iter().cloned().collect::<::syntax::tokenstream::TokenStream>()) } } diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml index 3d66e5a300787..06c5150fd13ad 100644 --- a/src/librustc_save_analysis/Cargo.toml +++ b/src/librustc_save_analysis/Cargo.toml @@ -12,5 +12,8 @@ crate-type = ["dylib"] log = { path = "../liblog" } rustc = { path = "../librustc" } syntax = { path = "../libsyntax" } -serialize = { path = "../libserialize" } -syntax_pos = { path = "../libsyntax_pos" } \ No newline at end of file +syntax_pos = { path = "../libsyntax_pos" } +rls-data = "0.1" +rls-span = "0.1" +# FIXME(#40527) should move rustc serialize out of tree +rustc-serialize = "0.3" diff --git a/src/librustc_save_analysis/csv_dumper.rs b/src/librustc_save_analysis/csv_dumper.rs index 0fd95500422ff..59340ae87ee5d 100644 --- a/src/librustc_save_analysis/csv_dumper.rs +++ b/src/librustc_save_analysis/csv_dumper.rs @@ -13,6 +13,8 @@ use std::io::Write; use super::external_data::*; use super::dump::Dump; +use rls_data::{SpanData, CratePreludeData}; + pub struct CsvDumper<'b, W: 'b> { output: &'b mut W } @@ -429,6 +431,6 @@ fn make_values_str(pairs: &[(&'static str, &str)]) -> String { fn span_extent_str(span: SpanData) -> String { format!("file_name,\"{}\",file_line,{},file_col,{},byte_start,{},\ file_line_end,{},file_col_end,{},byte_end,{}", - span.file_name, span.line_start, span.column_start, span.byte_start, - span.line_end, span.column_end, span.byte_end) + span.file_name.to_str().unwrap(), span.line_start.0, span.column_start.0, + span.byte_start, span.line_end.0, span.column_end.0, span.byte_end) } diff --git a/src/librustc_save_analysis/data.rs b/src/librustc_save_analysis/data.rs index 6caf81380e40d..d4ded71a33390 100644 --- a/src/librustc_save_analysis/data.rs +++ b/src/librustc_save_analysis/data.rs @@ -18,6 +18,8 @@ use rustc::hir::def_id::{CrateNum, DefId}; use syntax::ast::{self, Attribute, NodeId}; use syntax_pos::Span; +use rls_data::ExternalCrateData; + pub struct CrateData { pub name: String, pub number: u32, @@ -26,7 +28,7 @@ pub struct CrateData { /// Data for any entity in the Rust language. The actual data contained varies /// with the kind of entity being queried. See the nested structs for details. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub enum Data { /// Data for Enums. EnumData(EnumData), @@ -77,7 +79,7 @@ pub enum Data { VariableRefData(VariableRefData), } -#[derive(Eq, PartialEq, Clone, Copy, Debug, RustcEncodable)] +#[derive(Eq, PartialEq, Clone, Copy, Debug)] pub enum Visibility { Public, Restricted, @@ -107,7 +109,7 @@ impl<'a> From<&'a hir::Visibility> for Visibility { } /// Data for the prelude of a crate. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct CratePreludeData { pub crate_name: String, pub crate_root: String, @@ -115,16 +117,8 @@ pub struct CratePreludeData { pub span: Span, } -/// Data for external crates in the prelude of a crate. -#[derive(Debug, RustcEncodable)] -pub struct ExternalCrateData { - pub name: String, - pub num: CrateNum, - pub file_name: String, -} - /// Data for enum declarations. -#[derive(Clone, Debug, RustcEncodable)] +#[derive(Clone, Debug)] pub struct EnumData { pub id: NodeId, pub name: String, @@ -140,7 +134,7 @@ pub struct EnumData { } /// Data for extern crates. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct ExternCrateData { pub id: NodeId, pub name: String, @@ -151,7 +145,7 @@ pub struct ExternCrateData { } /// Data about a function call. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct FunctionCallData { pub span: Span, pub scope: NodeId, @@ -159,7 +153,7 @@ pub struct FunctionCallData { } /// Data for all kinds of functions and methods. -#[derive(Clone, Debug, RustcEncodable)] +#[derive(Clone, Debug)] pub struct FunctionData { pub id: NodeId, pub name: String, @@ -176,14 +170,14 @@ pub struct FunctionData { } /// Data about a function call. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct FunctionRefData { pub span: Span, pub scope: NodeId, pub ref_id: DefId, } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct ImplData { pub id: NodeId, pub span: Span, @@ -192,7 +186,7 @@ pub struct ImplData { pub self_ref: Option, } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] // FIXME: this struct should not exist. However, removing it requires heavy // refactoring of dump_visitor.rs. See PR 31838 for more info. pub struct ImplData2 { @@ -206,7 +200,7 @@ pub struct ImplData2 { pub self_ref: Option, } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct InheritanceData { pub span: Span, pub base_id: DefId, @@ -214,7 +208,7 @@ pub struct InheritanceData { } /// Data about a macro declaration. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct MacroData { pub span: Span, pub name: String, @@ -223,7 +217,7 @@ pub struct MacroData { } /// Data about a macro use. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct MacroUseData { pub span: Span, pub name: String, @@ -236,7 +230,7 @@ pub struct MacroUseData { } /// Data about a method call. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct MethodCallData { pub span: Span, pub scope: NodeId, @@ -245,7 +239,7 @@ pub struct MethodCallData { } /// Data for method declarations (methods with a body are treated as functions). -#[derive(Clone, Debug, RustcEncodable)] +#[derive(Clone, Debug)] pub struct MethodData { pub id: NodeId, pub name: String, @@ -262,7 +256,7 @@ pub struct MethodData { } /// Data for modules. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct ModData { pub id: NodeId, pub name: String, @@ -278,7 +272,7 @@ pub struct ModData { } /// Data for a reference to a module. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct ModRefData { pub span: Span, pub scope: NodeId, @@ -286,7 +280,7 @@ pub struct ModRefData { pub qualname: String } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct StructData { pub span: Span, pub name: String, @@ -302,7 +296,7 @@ pub struct StructData { pub attributes: Vec, } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct StructVariantData { pub span: Span, pub name: String, @@ -317,7 +311,7 @@ pub struct StructVariantData { pub attributes: Vec, } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct TraitData { pub span: Span, pub id: NodeId, @@ -332,7 +326,7 @@ pub struct TraitData { pub attributes: Vec, } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct TupleVariantData { pub span: Span, pub id: NodeId, @@ -348,7 +342,7 @@ pub struct TupleVariantData { } /// Data for a typedef. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct TypeDefData { pub id: NodeId, pub name: String, @@ -363,7 +357,7 @@ pub struct TypeDefData { } /// Data for a reference to a type or trait. -#[derive(Clone, Debug, RustcEncodable)] +#[derive(Clone, Debug)] pub struct TypeRefData { pub span: Span, pub scope: NodeId, @@ -371,7 +365,7 @@ pub struct TypeRefData { pub qualname: String, } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct UseData { pub id: NodeId, pub span: Span, @@ -381,7 +375,7 @@ pub struct UseData { pub visibility: Visibility, } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct UseGlobData { pub id: NodeId, pub span: Span, @@ -391,7 +385,7 @@ pub struct UseGlobData { } /// Data for local and global variables (consts and statics). -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct VariableData { pub id: NodeId, pub kind: VariableKind, @@ -408,7 +402,7 @@ pub struct VariableData { pub attributes: Vec, } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub enum VariableKind { Static, Const, @@ -418,7 +412,7 @@ pub enum VariableKind { /// Data for the use of some item (e.g., the use of a local variable, which /// will refer to that variables declaration (by ref_id)). -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct VariableRefData { pub name: String, pub span: Span, @@ -430,7 +424,7 @@ pub struct VariableRefData { /// Encodes information about the signature of a definition. This should have /// enough information to create a nice display about a definition without /// access to the source code. -#[derive(Clone, Debug, RustcEncodable)] +#[derive(Clone, Debug)] pub struct Signature { pub span: Span, pub text: String, @@ -444,7 +438,7 @@ pub struct Signature { /// An element of a signature. `start` and `end` are byte offsets into the `text` /// of the parent `Signature`. -#[derive(Clone, Debug, RustcEncodable)] +#[derive(Clone, Debug)] pub struct SigElement { pub id: DefId, pub start: usize, diff --git a/src/librustc_save_analysis/dump.rs b/src/librustc_save_analysis/dump.rs index 18241b394cc17..84e1fb03f624e 100644 --- a/src/librustc_save_analysis/dump.rs +++ b/src/librustc_save_analysis/dump.rs @@ -10,6 +10,8 @@ use super::external_data::*; +use rls_data::CratePreludeData; + pub trait Dump { fn crate_prelude(&mut self, CratePreludeData) {} fn enum_data(&mut self, EnumData) {} diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 61956e5cd9d66..f2aa89ba4b66e 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -29,7 +29,7 @@ use rustc::hir; use rustc::hir::def::Def; -use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; +use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::hir::map::{Node, NodeItem}; use rustc::session::Session; use rustc::ty::{self, TyCtxt, AssociatedItemContainer}; @@ -54,6 +54,8 @@ use super::external_data::{Lower, make_def_id}; use super::span_utils::SpanUtils; use super::recorder; +use rls_data::ExternalCrateData; + macro_rules! down_cast_data { ($id:ident, $kind:ident, $sp:expr) => { let $id = if let super::Data::$kind(data) = $id { @@ -137,7 +139,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { let lo_loc = self.span.sess.codemap().lookup_char_pos(c.span.lo); ExternalCrateData { name: c.name, - num: CrateNum::from_u32(c.number), + num: c.number, file_name: SpanUtils::make_path_string(&lo_loc.file.name), } }).collect(); diff --git a/src/librustc_save_analysis/external_data.rs b/src/librustc_save_analysis/external_data.rs index f038c2dc298ad..6fd2de97767e1 100644 --- a/src/librustc_save_analysis/external_data.rs +++ b/src/librustc_save_analysis/external_data.rs @@ -18,6 +18,9 @@ use syntax_pos::Span; use data::{self, Visibility, SigElement}; +use rls_data::{SpanData, CratePreludeData, Attribute}; +use rls_span::{Column, Row}; + // FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet pub trait Lower { type Target; @@ -35,41 +38,19 @@ pub fn null_def_id() -> DefId { } } -#[derive(Clone, Debug, RustcEncodable)] -pub struct SpanData { - pub file_name: String, - pub byte_start: u32, - pub byte_end: u32, - /// 1-based. - pub line_start: usize, - pub line_end: usize, - /// 1-based, character offset. - pub column_start: usize, - pub column_end: usize, -} - -impl SpanData { - pub fn from_span(span: Span, cm: &CodeMap) -> SpanData { - let start = cm.lookup_char_pos(span.lo); - let end = cm.lookup_char_pos(span.hi); - - SpanData { - file_name: start.file.name.clone(), - byte_start: span.lo.0, - byte_end: span.hi.0, - line_start: start.line, - line_end: end.line, - column_start: start.col.0 + 1, - column_end: end.col.0 + 1, - } - } -} +pub fn span_from_span(span: Span, cm: &CodeMap) -> SpanData { + let start = cm.lookup_char_pos(span.lo); + let end = cm.lookup_char_pos(span.hi); -/// Represent an arbitrary attribute on a code element -#[derive(Clone, Debug, RustcEncodable)] -pub struct Attribute { - value: String, - span: SpanData, + SpanData { + file_name: start.file.name.clone().into(), + byte_start: span.lo.0, + byte_end: span.hi.0, + line_start: Row::new_one_indexed(start.line as u32), + line_end: Row::new_one_indexed(end.line as u32), + column_start: Column::new_one_indexed(start.col.0 as u32 + 1), + column_end: Column::new_one_indexed(end.col.0 as u32 + 1), + } } impl Lower for Vec { @@ -91,20 +72,12 @@ impl Lower for Vec { Attribute { value: value, - span: SpanData::from_span(attr.span, tcx.sess.codemap()), + span: span_from_span(attr.span, tcx.sess.codemap()), } }).collect() } } -#[derive(Debug, RustcEncodable)] -pub struct CratePreludeData { - pub crate_name: String, - pub crate_root: String, - pub external_crates: Vec, - pub span: SpanData, -} - impl Lower for data::CratePreludeData { type Target = CratePreludeData; @@ -113,13 +86,13 @@ impl Lower for data::CratePreludeData { crate_name: self.crate_name, crate_root: self.crate_root, external_crates: self.external_crates, - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), } } } /// Data for enum declarations. -#[derive(Clone, Debug, RustcEncodable)] +#[derive(Clone, Debug)] pub struct EnumData { pub id: DefId, pub value: String, @@ -143,7 +116,7 @@ impl Lower for data::EnumData { name: self.name, value: self.value, qualname: self.qualname, - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.hir), variants: self.variants.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(), visibility: self.visibility, @@ -155,7 +128,7 @@ impl Lower for data::EnumData { } /// Data for extern crates. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct ExternCrateData { pub id: DefId, pub name: String, @@ -174,14 +147,14 @@ impl Lower for data::ExternCrateData { name: self.name, crate_num: self.crate_num, location: self.location, - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.hir), } } } /// Data about a function call. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct FunctionCallData { pub span: SpanData, pub scope: DefId, @@ -193,7 +166,7 @@ impl Lower for data::FunctionCallData { fn lower(self, tcx: TyCtxt) -> FunctionCallData { FunctionCallData { - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.hir), ref_id: self.ref_id, } @@ -201,7 +174,7 @@ impl Lower for data::FunctionCallData { } /// Data for all kinds of functions and methods. -#[derive(Clone, Debug, RustcEncodable)] +#[derive(Clone, Debug)] pub struct FunctionData { pub id: DefId, pub name: String, @@ -226,7 +199,7 @@ impl Lower for data::FunctionData { name: self.name, qualname: self.qualname, declaration: self.declaration, - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.hir), value: self.value, visibility: self.visibility, @@ -239,7 +212,7 @@ impl Lower for data::FunctionData { } /// Data about a function call. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct FunctionRefData { pub span: SpanData, pub scope: DefId, @@ -251,13 +224,13 @@ impl Lower for data::FunctionRefData { fn lower(self, tcx: TyCtxt) -> FunctionRefData { FunctionRefData { - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.hir), ref_id: self.ref_id, } } } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct ImplData { pub id: DefId, pub span: SpanData, @@ -272,7 +245,7 @@ impl Lower for data::ImplData { fn lower(self, tcx: TyCtxt) -> ImplData { ImplData { id: make_def_id(self.id, &tcx.hir), - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.hir), trait_ref: self.trait_ref, self_ref: self.self_ref, @@ -280,7 +253,7 @@ impl Lower for data::ImplData { } } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct InheritanceData { pub span: SpanData, pub base_id: DefId, @@ -292,7 +265,7 @@ impl Lower for data::InheritanceData { fn lower(self, tcx: TyCtxt) -> InheritanceData { InheritanceData { - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), base_id: self.base_id, deriv_id: make_def_id(self.deriv_id, &tcx.hir) } @@ -300,7 +273,7 @@ impl Lower for data::InheritanceData { } /// Data about a macro declaration. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct MacroData { pub span: SpanData, pub name: String, @@ -313,7 +286,7 @@ impl Lower for data::MacroData { fn lower(self, tcx: TyCtxt) -> MacroData { MacroData { - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), name: self.name, qualname: self.qualname, docs: self.docs, @@ -322,7 +295,7 @@ impl Lower for data::MacroData { } /// Data about a macro use. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct MacroUseData { pub span: SpanData, pub name: String, @@ -338,17 +311,17 @@ impl Lower for data::MacroUseData { fn lower(self, tcx: TyCtxt) -> MacroUseData { MacroUseData { - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), name: self.name, qualname: self.qualname, - callee_span: SpanData::from_span(self.callee_span, tcx.sess.codemap()), + callee_span: span_from_span(self.callee_span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.hir), } } } /// Data about a method call. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct MethodCallData { pub span: SpanData, pub scope: DefId, @@ -361,7 +334,7 @@ impl Lower for data::MethodCallData { fn lower(self, tcx: TyCtxt) -> MethodCallData { MethodCallData { - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.hir), ref_id: self.ref_id, decl_id: self.decl_id, @@ -370,7 +343,7 @@ impl Lower for data::MethodCallData { } /// Data for method declarations (methods with a body are treated as functions). -#[derive(Clone, Debug, RustcEncodable)] +#[derive(Clone, Debug)] pub struct MethodData { pub id: DefId, pub name: String, @@ -391,7 +364,7 @@ impl Lower for data::MethodData { fn lower(self, tcx: TyCtxt) -> MethodData { MethodData { - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), name: self.name, scope: make_def_id(self.scope, &tcx.hir), id: make_def_id(self.id, &tcx.hir), @@ -408,7 +381,7 @@ impl Lower for data::MethodData { } /// Data for modules. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct ModData { pub id: DefId, pub name: String, @@ -431,7 +404,7 @@ impl Lower for data::ModData { id: make_def_id(self.id, &tcx.hir), name: self.name, qualname: self.qualname, - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.hir), filename: self.filename, items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(), @@ -444,7 +417,7 @@ impl Lower for data::ModData { } /// Data for a reference to a module. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct ModRefData { pub span: SpanData, pub scope: DefId, @@ -457,7 +430,7 @@ impl Lower for data::ModRefData { fn lower(self, tcx: TyCtxt) -> ModRefData { ModRefData { - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.hir), ref_id: self.ref_id, qualname: self.qualname, @@ -465,7 +438,7 @@ impl Lower for data::ModRefData { } } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct StructData { pub span: SpanData, pub name: String, @@ -486,7 +459,7 @@ impl Lower for data::StructData { fn lower(self, tcx: TyCtxt) -> StructData { StructData { - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), name: self.name, id: make_def_id(self.id, &tcx.hir), ctor_id: make_def_id(self.ctor_id, &tcx.hir), @@ -502,7 +475,7 @@ impl Lower for data::StructData { } } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct StructVariantData { pub span: SpanData, pub name: String, @@ -522,7 +495,7 @@ impl Lower for data::StructVariantData { fn lower(self, tcx: TyCtxt) -> StructVariantData { StructVariantData { - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), name: self.name, id: make_def_id(self.id, &tcx.hir), qualname: self.qualname, @@ -537,7 +510,7 @@ impl Lower for data::StructVariantData { } } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct TraitData { pub span: SpanData, pub name: String, @@ -557,7 +530,7 @@ impl Lower for data::TraitData { fn lower(self, tcx: TyCtxt) -> TraitData { TraitData { - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), name: self.name, id: make_def_id(self.id, &tcx.hir), qualname: self.qualname, @@ -572,7 +545,7 @@ impl Lower for data::TraitData { } } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct TupleVariantData { pub span: SpanData, pub id: DefId, @@ -592,7 +565,7 @@ impl Lower for data::TupleVariantData { fn lower(self, tcx: TyCtxt) -> TupleVariantData { TupleVariantData { - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), id: make_def_id(self.id, &tcx.hir), name: self.name, qualname: self.qualname, @@ -608,7 +581,7 @@ impl Lower for data::TupleVariantData { } /// Data for a typedef. -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct TypeDefData { pub id: DefId, pub name: String, @@ -629,7 +602,7 @@ impl Lower for data::TypeDefData { TypeDefData { id: make_def_id(self.id, &tcx.hir), name: self.name, - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), qualname: self.qualname, value: self.value, visibility: self.visibility, @@ -642,7 +615,7 @@ impl Lower for data::TypeDefData { } /// Data for a reference to a type or trait. -#[derive(Clone, Debug, RustcEncodable)] +#[derive(Clone, Debug)] pub struct TypeRefData { pub span: SpanData, pub scope: DefId, @@ -655,7 +628,7 @@ impl Lower for data::TypeRefData { fn lower(self, tcx: TyCtxt) -> TypeRefData { TypeRefData { - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.hir), ref_id: self.ref_id, qualname: self.qualname, @@ -663,7 +636,7 @@ impl Lower for data::TypeRefData { } } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct UseData { pub id: DefId, pub span: SpanData, @@ -679,7 +652,7 @@ impl Lower for data::UseData { fn lower(self, tcx: TyCtxt) -> UseData { UseData { id: make_def_id(self.id, &tcx.hir), - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), name: self.name, mod_id: self.mod_id, scope: make_def_id(self.scope, &tcx.hir), @@ -688,7 +661,7 @@ impl Lower for data::UseData { } } -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct UseGlobData { pub id: DefId, pub span: SpanData, @@ -703,7 +676,7 @@ impl Lower for data::UseGlobData { fn lower(self, tcx: TyCtxt) -> UseGlobData { UseGlobData { id: make_def_id(self.id, &tcx.hir), - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), names: self.names, scope: make_def_id(self.scope, &tcx.hir), visibility: self.visibility, @@ -712,7 +685,7 @@ impl Lower for data::UseGlobData { } /// Data for local and global variables (consts and statics). -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct VariableData { pub id: DefId, pub name: String, @@ -738,7 +711,7 @@ impl Lower for data::VariableData { kind: self.kind, name: self.name, qualname: self.qualname, - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.hir), value: self.value, type_value: self.type_value, @@ -753,7 +726,7 @@ impl Lower for data::VariableData { /// Data for the use of some item (e.g., the use of a local variable, which /// will refer to that variables declaration (by ref_id)). -#[derive(Debug, RustcEncodable)] +#[derive(Debug)] pub struct VariableRefData { pub name: String, pub span: SpanData, @@ -767,14 +740,14 @@ impl Lower for data::VariableRefData { fn lower(self, tcx: TyCtxt) -> VariableRefData { VariableRefData { name: self.name, - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.hir), ref_id: self.ref_id, } } } -#[derive(Clone, Debug, RustcEncodable)] +#[derive(Clone, Debug)] pub struct Signature { pub span: SpanData, pub text: String, @@ -791,7 +764,7 @@ impl Lower for data::Signature { fn lower(self, tcx: TyCtxt) -> Signature { Signature { - span: SpanData::from_span(self.span, tcx.sess.codemap()), + span: span_from_span(self.span, tcx.sess.codemap()), text: self.text, ident_start: self.ident_start, ident_end: self.ident_end, diff --git a/src/librustc_save_analysis/json_api_dumper.rs b/src/librustc_save_analysis/json_api_dumper.rs index 277535f9e6513..41221ad986379 100644 --- a/src/librustc_save_analysis/json_api_dumper.rs +++ b/src/librustc_save_analysis/json_api_dumper.rs @@ -10,13 +10,14 @@ use std::io::Write; -use rustc::hir::def_id::DefId; use rustc_serialize::json::as_json; use external_data::*; -use data::{VariableKind, Visibility, SigElement}; +use data::{VariableKind, Visibility}; use dump::Dump; -use super::Format; +use json_dumper::id_from_def_id; + +use rls_data::{Analysis, Import, ImportKind, Def, DefKind, CratePreludeData}; // A dumper to dump a restricted set of JSON information, designed for use with @@ -24,8 +25,7 @@ use super::Format; // information here, and (for example) generate Rustdoc URLs, but don't need // information for navigating the source of the crate. // Relative to the regular JSON save-analysis info, this form is filtered to -// remove non-visible items, but includes some extra info for items (e.g., the -// parent field for finding the struct to which a field belongs). +// remove non-visible items. pub struct JsonApiDumper<'b, W: Write + 'b> { output: &'b mut W, result: Analysis, @@ -48,7 +48,7 @@ impl<'b, W: Write> Drop for JsonApiDumper<'b, W> { macro_rules! impl_fn { ($fn_name: ident, $data_type: ident, $bucket: ident) => { fn $fn_name(&mut self, data: $data_type) { - if let Some(datum) = From::from(data) { + if let Some(datum) = data.into() { self.result.$bucket.push(datum); } } @@ -77,11 +77,11 @@ impl<'b, W: Write + 'b> Dump for JsonApiDumper<'b, W> { fn impl_data(&mut self, data: ImplData) { if data.self_ref.is_some() { - self.result.relations.push(From::from(data)); + self.result.relations.push(data.into()); } } fn inheritance(&mut self, data: InheritanceData) { - self.result.relations.push(From::from(data)); + self.result.relations.push(data.into()); } } @@ -90,426 +90,261 @@ impl<'b, W: Write + 'b> Dump for JsonApiDumper<'b, W> { // method, but not the supplied method). In both cases, we are currently // ignoring it. -#[derive(Debug, RustcEncodable)] -struct Analysis { - kind: Format, - prelude: Option, - imports: Vec, - defs: Vec, - relations: Vec, - // These two fields are dummies so that clients can parse the two kinds of - // JSON data in the same way. - refs: Vec<()>, - macro_refs: Vec<()>, -} - -impl Analysis { - fn new() -> Analysis { - Analysis { - kind: Format::JsonApi, - prelude: None, - imports: vec![], - defs: vec![], - relations: vec![], - refs: vec![], - macro_refs: vec![], - } - } -} - -// DefId::index is a newtype and so the JSON serialisation is ugly. Therefore -// we use our own Id which is the same, but without the newtype. -#[derive(Debug, RustcEncodable)] -struct Id { - krate: u32, - index: u32, -} - -impl From for Id { - fn from(id: DefId) -> Id { - Id { - krate: id.krate.as_u32(), - index: id.index.as_u32(), - } - } -} - -#[derive(Debug, RustcEncodable)] -struct Import { - kind: ImportKind, - id: Id, - span: SpanData, - name: String, - value: String, -} - -#[derive(Debug, RustcEncodable)] -enum ImportKind { - Use, - GlobUse, -} - -impl From for Option { - fn from(data: UseData) -> Option { - match data.visibility { +impl Into> for UseData { + fn into(self) -> Option { + match self.visibility { Visibility::Public => Some(Import { kind: ImportKind::Use, - id: From::from(data.id), - span: data.span, - name: data.name, + ref_id: self.mod_id.map(|id| id_from_def_id(id)), + span: self.span, + name: self.name, value: String::new(), }), _ => None, } } } -impl From for Option { - fn from(data: UseGlobData) -> Option { - match data.visibility { +impl Into> for UseGlobData { + fn into(self) -> Option { + match self.visibility { Visibility::Public => Some(Import { kind: ImportKind::GlobUse, - id: From::from(data.id), - span: data.span, + ref_id: None, + span: self.span, name: "*".to_owned(), - value: data.names.join(", "), + value: self.names.join(", "), }), _ => None, } } } -#[derive(Debug, RustcEncodable)] -struct Def { - kind: DefKind, - id: Id, - span: SpanData, - name: String, - qualname: String, - value: String, - parent: Option, - children: Vec, - decl_id: Option, - docs: String, - sig: Option, -} - -#[derive(Debug, RustcEncodable)] -enum DefKind { - // value = variant names - Enum, - // value = enum name + variant name + types - Tuple, - // value = [enum name +] name + fields - Struct, - // value = signature - Trait, - // value = type + generics - Function, - // value = type + generics - Method, - // No id, no value. - Macro, - // value = file_name - Mod, - // value = aliased type - Type, - // value = type and init expression (for all variable kinds). - Static, - Const, - Field, -} - -impl From for Option { - fn from(data: EnumData) -> Option { - match data.visibility { +impl Into> for EnumData { + fn into(self) -> Option { + match self.visibility { Visibility::Public => Some(Def { kind: DefKind::Enum, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, parent: None, - children: data.variants.into_iter().map(|id| From::from(id)).collect(), + children: self.variants.into_iter().map(|id| id_from_def_id(id)).collect(), decl_id: None, - docs: data.docs, - sig: Some(From::from(data.sig)), + docs: self.docs, + sig: Some(self.sig.into()), + attributes: vec![], }), _ => None, } } } -impl From for Option { - fn from(data: TupleVariantData) -> Option { +impl Into> for TupleVariantData { + fn into(self) -> Option { Some(Def { kind: DefKind::Tuple, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, - parent: data.parent.map(|id| From::from(id)), + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, + parent: self.parent.map(|id| id_from_def_id(id)), children: vec![], decl_id: None, - docs: data.docs, - sig: Some(From::from(data.sig)), + docs: self.docs, + sig: Some(self.sig.into()), + attributes: vec![], }) } } -impl From for Option { - fn from(data: StructVariantData) -> Option { +impl Into> for StructVariantData { + fn into(self) -> Option { Some(Def { kind: DefKind::Struct, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, - parent: data.parent.map(|id| From::from(id)), + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, + parent: self.parent.map(|id| id_from_def_id(id)), children: vec![], decl_id: None, - docs: data.docs, - sig: Some(From::from(data.sig)), + docs: self.docs, + sig: Some(self.sig.into()), + attributes: vec![], }) } } -impl From for Option { - fn from(data: StructData) -> Option { - match data.visibility { +impl Into> for StructData { + fn into(self) -> Option { + match self.visibility { Visibility::Public => Some(Def { kind: DefKind::Struct, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, parent: None, - children: data.fields.into_iter().map(|id| From::from(id)).collect(), + children: self.fields.into_iter().map(|id| id_from_def_id(id)).collect(), decl_id: None, - docs: data.docs, - sig: Some(From::from(data.sig)), + docs: self.docs, + sig: Some(self.sig.into()), + attributes: vec![], }), _ => None, } } } -impl From for Option { - fn from(data: TraitData) -> Option { - match data.visibility { +impl Into> for TraitData { + fn into(self) -> Option { + match self.visibility { Visibility::Public => Some(Def { kind: DefKind::Trait, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, - children: data.items.into_iter().map(|id| From::from(id)).collect(), + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, + children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(), parent: None, decl_id: None, - docs: data.docs, - sig: Some(From::from(data.sig)), + docs: self.docs, + sig: Some(self.sig.into()), + attributes: vec![], }), _ => None, } } } -impl From for Option { - fn from(data: FunctionData) -> Option { - match data.visibility { +impl Into> for FunctionData { + fn into(self) -> Option { + match self.visibility { Visibility::Public => Some(Def { kind: DefKind::Function, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, children: vec![], - parent: data.parent.map(|id| From::from(id)), + parent: self.parent.map(|id| id_from_def_id(id)), decl_id: None, - docs: data.docs, - sig: Some(From::from(data.sig)), + docs: self.docs, + sig: Some(self.sig.into()), + attributes: vec![], }), _ => None, } } } -impl From for Option { - fn from(data: MethodData) -> Option { - match data.visibility { +impl Into> for MethodData { + fn into(self) -> Option { + match self.visibility { Visibility::Public => Some(Def { kind: DefKind::Method, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, children: vec![], - parent: data.parent.map(|id| From::from(id)), - decl_id: data.decl_id.map(|id| From::from(id)), - docs: data.docs, - sig: Some(From::from(data.sig)), + parent: self.parent.map(|id| id_from_def_id(id)), + decl_id: self.decl_id.map(|id| id_from_def_id(id)), + docs: self.docs, + sig: Some(self.sig.into()), + attributes: vec![], }), _ => None, } } } -impl From for Option { - fn from(data: MacroData) -> Option { +impl Into> for MacroData { + fn into(self) -> Option { Some(Def { kind: DefKind::Macro, - id: From::from(null_def_id()), - span: data.span, - name: data.name, - qualname: data.qualname, + id: id_from_def_id(null_def_id()), + span: self.span, + name: self.name, + qualname: self.qualname, value: String::new(), children: vec![], parent: None, decl_id: None, - docs: data.docs, + docs: self.docs, sig: None, + attributes: vec![], }) } } -impl From for Option { - fn from(data:ModData) -> Option { - match data.visibility { +impl Into> for ModData { + fn into(self) -> Option { + match self.visibility { Visibility::Public => Some(Def { kind: DefKind::Mod, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.filename, - children: data.items.into_iter().map(|id| From::from(id)).collect(), + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.filename, + children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(), parent: None, decl_id: None, - docs: data.docs, - sig: Some(From::from(data.sig)), + docs: self.docs, + sig: Some(self.sig.into()), + attributes: vec![], }), _ => None, } } } -impl From for Option { - fn from(data: TypeDefData) -> Option { - match data.visibility { +impl Into> for TypeDefData { + fn into(self) -> Option { + match self.visibility { Visibility::Public => Some(Def { kind: DefKind::Type, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, children: vec![], - parent: data.parent.map(|id| From::from(id)), + parent: self.parent.map(|id| id_from_def_id(id)), decl_id: None, docs: String::new(), - sig: data.sig.map(|s| From::from(s)), + sig: self.sig.map(|s| s.into()), + attributes: vec![], }), _ => None, } } } -impl From for Option { - fn from(data: VariableData) -> Option { - match data.visibility { +impl Into> for VariableData { + fn into(self) -> Option { + match self.visibility { Visibility::Public => Some(Def { - kind: match data.kind { + kind: match self.kind { VariableKind::Static => DefKind::Static, VariableKind::Const => DefKind::Const, VariableKind::Local => { return None } VariableKind::Field => DefKind::Field, }, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, children: vec![], - parent: data.parent.map(|id| From::from(id)), + parent: self.parent.map(|id| id_from_def_id(id)), decl_id: None, - docs: data.docs, - sig: data.sig.map(|s| From::from(s)), + docs: self.docs, + sig: self.sig.map(|s| s.into()), + attributes: vec![], }), _ => None, } } } - -#[derive(Debug, RustcEncodable)] -struct Relation { - span: SpanData, - kind: RelationKind, - from: Id, - to: Id, -} - -#[derive(Debug, RustcEncodable)] -enum RelationKind { - Impl, - SuperTrait, -} - -impl From for Relation { - fn from(data: ImplData) -> Relation { - Relation { - span: data.span, - kind: RelationKind::Impl, - from: From::from(data.self_ref.unwrap_or(null_def_id())), - to: From::from(data.trait_ref.unwrap_or(null_def_id())), - } - } -} - -impl From for Relation { - fn from(data: InheritanceData) -> Relation { - Relation { - span: data.span, - kind: RelationKind::SuperTrait, - from: From::from(data.base_id), - to: From::from(data.deriv_id), - } - } -} - -#[derive(Debug, RustcEncodable)] -pub struct JsonSignature { - span: SpanData, - text: String, - ident_start: usize, - ident_end: usize, - defs: Vec, - refs: Vec, -} - -impl From for JsonSignature { - fn from(data: Signature) -> JsonSignature { - JsonSignature { - span: data.span, - text: data.text, - ident_start: data.ident_start, - ident_end: data.ident_end, - defs: data.defs.into_iter().map(|s| From::from(s)).collect(), - refs: data.refs.into_iter().map(|s| From::from(s)).collect(), - } - } -} - -#[derive(Debug, RustcEncodable)] -pub struct JsonSigElement { - id: Id, - start: usize, - end: usize, -} - -impl From for JsonSigElement { - fn from(data: SigElement) -> JsonSigElement { - JsonSigElement { - id: From::from(data.id), - start: data.start, - end: data.end, - } - } -} diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs index 1b72489f83c67..acc877d394775 100644 --- a/src/librustc_save_analysis/json_dumper.rs +++ b/src/librustc_save_analysis/json_dumper.rs @@ -13,10 +13,14 @@ use std::io::Write; use rustc::hir::def_id::DefId; use rustc_serialize::json::as_json; +use rls_data::{self, Id, Analysis, Import, ImportKind, Def, DefKind, Ref, RefKind, MacroRef, + Relation, RelationKind, Signature, SigElement, CratePreludeData}; +use rls_span::{Column, Row}; + +use external_data; use external_data::*; -use data::{VariableKind, SigElement}; +use data::{self, VariableKind}; use dump::Dump; -use super::Format; pub struct JsonDumper<'b, W: Write + 'b> { output: &'b mut W, @@ -40,7 +44,7 @@ impl<'b, W: Write> Drop for JsonDumper<'b, W> { macro_rules! impl_fn { ($fn_name: ident, $data_type: ident, $bucket: ident) => { fn $fn_name(&mut self, data: $data_type) { - self.result.$bucket.push(From::from(data)); + self.result.$bucket.push(data.into()); } } } @@ -75,21 +79,22 @@ impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> { impl_fn!(macro_use, MacroUseData, macro_refs); fn mod_data(&mut self, data: ModData) { - let id: Id = From::from(data.id); + let id: Id = id_from_def_id(data.id); let mut def = Def { kind: DefKind::Mod, id: id, - span: data.span, + span: data.span.into(), name: data.name, qualname: data.qualname, value: data.filename, - children: data.items.into_iter().map(|id| From::from(id)).collect(), + parent: None, + children: data.items.into_iter().map(|id| id_from_def_id(id)).collect(), decl_id: None, docs: data.docs, - sig: Some(From::from(data.sig)), - attributes: data.attributes, + sig: Some(data.sig.into()), + attributes: data.attributes.into_iter().map(|a| a.into()).collect(), }; - if def.span.file_name != def.value { + if def.span.file_name.to_str().unwrap() != def.value { // If the module is an out-of-line defintion, then we'll make the // defintion the first character in the module's file and turn the // the declaration into a reference to it. @@ -99,14 +104,14 @@ impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> { ref_id: id, }; self.result.refs.push(rf); - def.span = SpanData { - file_name: def.value.clone(), + def.span = rls_data::SpanData { + file_name: def.value.clone().into(), byte_start: 0, byte_end: 0, - line_start: 1, - line_end: 1, - column_start: 1, - column_end: 1, + line_start: Row::new_one_indexed(1), + line_end: Row::new_one_indexed(1), + column_start: Column::new_one_indexed(1), + column_end: Column::new_one_indexed(1), } } @@ -115,11 +120,11 @@ impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> { fn impl_data(&mut self, data: ImplData) { if data.self_ref.is_some() { - self.result.relations.push(From::from(data)); + self.result.relations.push(data.into()); } } fn inheritance(&mut self, data: InheritanceData) { - self.result.relations.push(From::from(data)); + self.result.relations.push(data.into()); } } @@ -129,476 +134,342 @@ impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> { // method, but not the supplied method). In both cases, we are currently // ignoring it. -#[derive(Debug, RustcEncodable)] -struct Analysis { - kind: Format, - prelude: Option, - imports: Vec, - defs: Vec, - refs: Vec, - macro_refs: Vec, - relations: Vec, -} - -impl Analysis { - fn new() -> Analysis { - Analysis { - kind: Format::Json, - prelude: None, - imports: vec![], - defs: vec![], - refs: vec![], - macro_refs: vec![], - relations: vec![], - } - } -} - // DefId::index is a newtype and so the JSON serialisation is ugly. Therefore // we use our own Id which is the same, but without the newtype. -#[derive(Clone, Copy, Debug, RustcEncodable)] -struct Id { - krate: u32, - index: u32, -} - -impl From for Id { - fn from(id: DefId) -> Id { - Id { - krate: id.krate.as_u32(), - index: id.index.as_u32(), - } +pub fn id_from_def_id(id: DefId) -> Id { + Id { + krate: id.krate.as_u32(), + index: id.index.as_u32(), } } -#[derive(Debug, RustcEncodable)] -struct Import { - kind: ImportKind, - ref_id: Option, - span: SpanData, - name: String, - value: String, -} - -#[derive(Debug, RustcEncodable)] -enum ImportKind { - ExternCrate, - Use, - GlobUse, -} - -impl From for Import { - fn from(data: ExternCrateData) -> Import { +impl Into for ExternCrateData { + fn into(self) -> Import { Import { kind: ImportKind::ExternCrate, ref_id: None, - span: data.span, - name: data.name, + span: self.span, + name: self.name, value: String::new(), } } } -impl From for Import { - fn from(data: UseData) -> Import { +impl Into for UseData { + fn into(self) -> Import { Import { kind: ImportKind::Use, - ref_id: data.mod_id.map(|id| From::from(id)), - span: data.span, - name: data.name, + ref_id: self.mod_id.map(|id| id_from_def_id(id)), + span: self.span, + name: self.name, value: String::new(), } } } -impl From for Import { - fn from(data: UseGlobData) -> Import { +impl Into for UseGlobData { + fn into(self) -> Import { Import { kind: ImportKind::GlobUse, ref_id: None, - span: data.span, + span: self.span, name: "*".to_owned(), - value: data.names.join(", "), + value: self.names.join(", "), } } } -#[derive(Debug, RustcEncodable)] -struct Def { - kind: DefKind, - id: Id, - span: SpanData, - name: String, - qualname: String, - value: String, - children: Vec, - decl_id: Option, - docs: String, - sig: Option, - attributes: Vec, -} - -#[derive(Debug, RustcEncodable)] -enum DefKind { - // value = variant names - Enum, - // value = enum name + variant name + types - Tuple, - // value = [enum name +] name + fields - Struct, - // value = signature - Trait, - // value = type + generics - Function, - // value = type + generics - Method, - // No id, no value. - Macro, - // value = file_name - Mod, - // value = aliased type - Type, - // value = type and init expression (for all variable kinds). - Local, - Static, - Const, - Field, -} - -impl From for Def { - fn from(data: EnumData) -> Def { +impl Into for EnumData { + fn into(self) -> Def { Def { kind: DefKind::Enum, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, - children: data.variants.into_iter().map(|id| From::from(id)).collect(), + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, + parent: None, + children: self.variants.into_iter().map(|id| id_from_def_id(id)).collect(), decl_id: None, - docs: data.docs, - sig: Some(From::from(data.sig)), - attributes: data.attributes, + docs: self.docs, + sig: Some(self.sig.into()), + attributes: self.attributes, } } } -impl From for Def { - fn from(data: TupleVariantData) -> Def { +impl Into for TupleVariantData { + fn into(self) -> Def { Def { kind: DefKind::Tuple, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, + parent: None, children: vec![], decl_id: None, - docs: data.docs, - sig: Some(From::from(data.sig)), - attributes: data.attributes, + docs: self.docs, + sig: Some(self.sig.into()), + attributes: self.attributes, } } } -impl From for Def { - fn from(data: StructVariantData) -> Def { +impl Into for StructVariantData { + fn into(self) -> Def { Def { kind: DefKind::Struct, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, + parent: None, children: vec![], decl_id: None, - docs: data.docs, - sig: Some(From::from(data.sig)), - attributes: data.attributes, + docs: self.docs, + sig: Some(self.sig.into()), + attributes: self.attributes, } } } -impl From for Def { - fn from(data: StructData) -> Def { +impl Into for StructData { + fn into(self) -> Def { Def { kind: DefKind::Struct, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, - children: data.fields.into_iter().map(|id| From::from(id)).collect(), + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, + parent: None, + children: self.fields.into_iter().map(|id| id_from_def_id(id)).collect(), decl_id: None, - docs: data.docs, - sig: Some(From::from(data.sig)), - attributes: data.attributes, + docs: self.docs, + sig: Some(self.sig.into()), + attributes: self.attributes, } } } -impl From for Def { - fn from(data: TraitData) -> Def { +impl Into for TraitData { + fn into(self) -> Def { Def { kind: DefKind::Trait, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, - children: data.items.into_iter().map(|id| From::from(id)).collect(), + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, + parent: None, + children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(), decl_id: None, - docs: data.docs, - sig: Some(From::from(data.sig)), - attributes: data.attributes, + docs: self.docs, + sig: Some(self.sig.into()), + attributes: self.attributes, } } } -impl From for Def { - fn from(data: FunctionData) -> Def { +impl Into for FunctionData { + fn into(self) -> Def { Def { kind: DefKind::Function, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, + parent: None, children: vec![], decl_id: None, - docs: data.docs, - sig: Some(From::from(data.sig)), - attributes: data.attributes, + docs: self.docs, + sig: Some(self.sig.into()), + attributes: self.attributes, } } } -impl From for Def { - fn from(data: MethodData) -> Def { +impl Into for MethodData { + fn into(self) -> Def { Def { kind: DefKind::Method, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, + parent: None, children: vec![], - decl_id: data.decl_id.map(|id| From::from(id)), - docs: data.docs, - sig: Some(From::from(data.sig)), - attributes: data.attributes, + decl_id: self.decl_id.map(|id| id_from_def_id(id)), + docs: self.docs, + sig: Some(self.sig.into()), + attributes: self.attributes, } } } -impl From for Def { - fn from(data: MacroData) -> Def { +impl Into for MacroData { + fn into(self) -> Def { Def { kind: DefKind::Macro, - id: From::from(null_def_id()), - span: data.span, - name: data.name, - qualname: data.qualname, + id: id_from_def_id(null_def_id()), + span: self.span, + name: self.name, + qualname: self.qualname, value: String::new(), + parent: None, children: vec![], decl_id: None, - docs: data.docs, + docs: self.docs, sig: None, attributes: vec![], } } } -impl From for Def { - fn from(data: TypeDefData) -> Def { +impl Into for TypeDefData { + fn into(self) -> Def { Def { kind: DefKind::Type, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.value, + parent: None, children: vec![], decl_id: None, docs: String::new(), - sig: data.sig.map(|s| From::from(s)), - attributes: data.attributes, + sig: self.sig.map(|s| s.into()), + attributes: self.attributes, } } } -impl From for Def { - fn from(data: VariableData) -> Def { +impl Into for VariableData { + fn into(self) -> Def { Def { - kind: match data.kind { + kind: match self.kind { VariableKind::Static => DefKind::Static, VariableKind::Const => DefKind::Const, VariableKind::Local => DefKind::Local, VariableKind::Field => DefKind::Field, }, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.type_value, + id: id_from_def_id(self.id), + span: self.span, + name: self.name, + qualname: self.qualname, + value: self.type_value, + parent: None, children: vec![], decl_id: None, - docs: data.docs, + docs: self.docs, sig: None, - attributes: data.attributes, + attributes: self.attributes, } } } -#[derive(Debug, RustcEncodable)] -enum RefKind { - Function, - Mod, - Type, - Variable, -} - -#[derive(Debug, RustcEncodable)] -struct Ref { - kind: RefKind, - span: SpanData, - ref_id: Id, -} - -impl From for Ref { - fn from(data: FunctionRefData) -> Ref { +impl Into for FunctionRefData { + fn into(self) -> Ref { Ref { kind: RefKind::Function, - span: data.span, - ref_id: From::from(data.ref_id), + span: self.span, + ref_id: id_from_def_id(self.ref_id), } } } -impl From for Ref { - fn from(data: FunctionCallData) -> Ref { +impl Into for FunctionCallData { + fn into(self) -> Ref { Ref { kind: RefKind::Function, - span: data.span, - ref_id: From::from(data.ref_id), + span: self.span, + ref_id: id_from_def_id(self.ref_id), } } } -impl From for Ref { - fn from(data: MethodCallData) -> Ref { +impl Into for MethodCallData { + fn into(self) -> Ref { Ref { kind: RefKind::Function, - span: data.span, - ref_id: From::from(data.ref_id.or(data.decl_id).unwrap_or(null_def_id())), + span: self.span, + ref_id: id_from_def_id(self.ref_id.or(self.decl_id).unwrap_or(null_def_id())), } } } -impl From for Ref { - fn from(data: ModRefData) -> Ref { +impl Into for ModRefData { + fn into(self) -> Ref { Ref { kind: RefKind::Mod, - span: data.span, - ref_id: From::from(data.ref_id.unwrap_or(null_def_id())), + span: self.span, + ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())), } } } -impl From for Ref { - fn from(data: TypeRefData) -> Ref { +impl Into for TypeRefData { + fn into(self) -> Ref { Ref { kind: RefKind::Type, - span: data.span, - ref_id: From::from(data.ref_id.unwrap_or(null_def_id())), + span: self.span, + ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())), } } } -impl From for Ref { - fn from(data: VariableRefData) -> Ref { +impl Into for VariableRefData { + fn into(self) -> Ref { Ref { kind: RefKind::Variable, - span: data.span, - ref_id: From::from(data.ref_id), + span: self.span, + ref_id: id_from_def_id(self.ref_id), } } } -#[derive(Debug, RustcEncodable)] -struct MacroRef { - span: SpanData, - qualname: String, - callee_span: SpanData, -} - -impl From for MacroRef { - fn from(data: MacroUseData) -> MacroRef { +impl Into for MacroUseData { + fn into(self) -> MacroRef { MacroRef { - span: data.span, - qualname: data.qualname, - callee_span: data.callee_span, + span: self.span, + qualname: self.qualname, + callee_span: self.callee_span.into(), } } } -#[derive(Debug, RustcEncodable)] -struct Relation { - span: SpanData, - kind: RelationKind, - from: Id, - to: Id, -} - -#[derive(Debug, RustcEncodable)] -enum RelationKind { - Impl, - SuperTrait, -} - -impl From for Relation { - fn from(data: ImplData) -> Relation { +impl Into for ImplData { + fn into(self) -> Relation { Relation { - span: data.span, + span: self.span, kind: RelationKind::Impl, - from: From::from(data.self_ref.unwrap_or(null_def_id())), - to: From::from(data.trait_ref.unwrap_or(null_def_id())), + from: id_from_def_id(self.self_ref.unwrap_or(null_def_id())), + to: id_from_def_id(self.trait_ref.unwrap_or(null_def_id())), } } } -impl From for Relation { - fn from(data: InheritanceData) -> Relation { +impl Into for InheritanceData { + fn into(self) -> Relation { Relation { - span: data.span, + span: self.span, kind: RelationKind::SuperTrait, - from: From::from(data.base_id), - to: From::from(data.deriv_id), + from: id_from_def_id(self.base_id), + to: id_from_def_id(self.deriv_id), } } } -#[derive(Debug, RustcEncodable)] -pub struct JsonSignature { - span: SpanData, - text: String, - ident_start: usize, - ident_end: usize, - defs: Vec, - refs: Vec, -} - -impl From for JsonSignature { - fn from(data: Signature) -> JsonSignature { - JsonSignature { - span: data.span, - text: data.text, - ident_start: data.ident_start, - ident_end: data.ident_end, - defs: data.defs.into_iter().map(|s| From::from(s)).collect(), - refs: data.refs.into_iter().map(|s| From::from(s)).collect(), +impl Into for external_data::Signature { + fn into(self) -> Signature { + Signature { + span: self.span, + text: self.text, + ident_start: self.ident_start, + ident_end: self.ident_end, + defs: self.defs.into_iter().map(|s| s.into()).collect(), + refs: self.refs.into_iter().map(|s| s.into()).collect(), } } } -#[derive(Debug, RustcEncodable)] -pub struct JsonSigElement { - id: Id, - start: usize, - end: usize, -} - -impl From for JsonSigElement { - fn from(data: SigElement) -> JsonSigElement { - JsonSigElement { - id: From::from(data.id), - start: data.start, - end: data.end, +impl Into for data::SigElement { + fn into(self) -> SigElement { + SigElement { + id: id_from_def_id(self.id), + start: self.start, + end: self.end, } } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 581b23d52142d..5e2b1df9d34f8 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -26,9 +26,12 @@ #[macro_use] extern crate log; #[macro_use] extern crate syntax; -extern crate serialize as rustc_serialize; +extern crate rustc_serialize; extern crate syntax_pos; +extern crate rls_data; +extern crate rls_span; + mod csv_dumper; mod json_api_dumper; diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index b7aedb742db02..762bf8592ffcc 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -261,7 +261,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, "ctlz" | "cttz" | "ctpop" | "bswap" | "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" | "overflowing_add" | "overflowing_sub" | "overflowing_mul" | - "unchecked_div" | "unchecked_rem" => { + "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" => { let sty = &arg_tys[0].sty; match int_type_width_signed(sty, ccx) { Some((width, signed)) => @@ -311,6 +311,13 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, } else { bcx.urem(llargs[0], llargs[1]) }, + "unchecked_shl" => bcx.shl(llargs[0], llargs[1]), + "unchecked_shr" => + if signed { + bcx.ashr(llargs[0], llargs[1]) + } else { + bcx.lshr(llargs[0], llargs[1]) + }, _ => bug!(), }, None => { diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 4b88f5acf42da..529ee107c46ce 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -254,7 +254,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Call the generic checker. let expected_arg_tys = - self.expected_types_for_fn_args(call_expr.span, + self.expected_inputs_for_expected_output(call_expr.span, expected, fn_sig.output(), fn_sig.inputs()); @@ -280,7 +280,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // do know the types expected for each argument and the return // type. - let expected_arg_tys = self.expected_types_for_fn_args(call_expr.span, + let expected_arg_tys = self.expected_inputs_for_expected_output(call_expr.span, expected, fn_sig.output().clone(), fn_sig.inputs()); diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 28996b40cfdfe..2861fd288326b 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -273,6 +273,8 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "unchecked_div" | "unchecked_rem" => (1, vec![param(0), param(0)], param(0)), + "unchecked_shl" | "unchecked_shr" => + (1, vec![param(0), param(0)], param(0)), "overflowing_add" | "overflowing_sub" | "overflowing_mul" => (1, vec![param(0), param(0)], param(0)), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 5a582a523ea1c..f36254a8a10ea 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2292,7 +2292,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match method_fn_ty.sty { ty::TyFnDef(def_id, .., ref fty) => { // HACK(eddyb) ignore self in the definition (see above). - let expected_arg_tys = self.expected_types_for_fn_args( + let expected_arg_tys = self.expected_inputs_for_expected_output( sp, expected, fty.0.output(), @@ -2645,14 +2645,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { TypeAndSubsts { substs: substs, ty: substd_ty } } - /// Unifies the return type with the expected type early, for more coercions - /// and forward type information on the argument expressions. - fn expected_types_for_fn_args(&self, - call_span: Span, - expected_ret: Expectation<'tcx>, - formal_ret: Ty<'tcx>, - formal_args: &[Ty<'tcx>]) - -> Vec> { + /// Unifies the output type with the expected type early, for more coercions + /// and forward type information on the input expressions. + fn expected_inputs_for_expected_output(&self, + call_span: Span, + expected_ret: Expectation<'tcx>, + formal_ret: Ty<'tcx>, + formal_args: &[Ty<'tcx>]) + -> Vec> { let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| { self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || { // Attempt to apply a subtyping relationship between the formal @@ -2675,7 +2675,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }).collect()) }).ok() }).unwrap_or(vec![]); - debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})", + debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})", formal_args, formal_ret, expected_args, expected_ret); expected_args @@ -3032,14 +3032,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn check_expr_struct_fields(&self, adt_ty: Ty<'tcx>, + expected: Expectation<'tcx>, expr_id: ast::NodeId, span: Span, variant: &'tcx ty::VariantDef, ast_fields: &'gcx [hir::Field], check_completeness: bool) { let tcx = self.tcx; - let (substs, adt_kind, kind_name) = match adt_ty.sty { - ty::TyAdt(adt, substs) => (substs, adt.adt_kind(), adt.variant_descr()), + + let adt_ty_hint = + self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty]) + .get(0).cloned().unwrap_or(adt_ty); + + let (substs, hint_substs, adt_kind, kind_name) = match (&adt_ty.sty, &adt_ty_hint.sty) { + (&ty::TyAdt(adt, substs), &ty::TyAdt(_, hint_substs)) => { + (substs, hint_substs, adt.adt_kind(), adt.variant_descr()) + } _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields") }; @@ -3054,10 +3062,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Typecheck each field. for field in ast_fields { - let expected_field_type; + let final_field_type; + let field_type_hint; if let Some(v_field) = remaining_fields.remove(&field.name.node) { - expected_field_type = self.field_ty(field.span, v_field, substs); + final_field_type = self.field_ty(field.span, v_field, substs); + field_type_hint = self.field_ty(field.span, v_field, hint_substs); seen_fields.insert(field.name.node, field.span); @@ -3069,7 +3079,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } else { error_happened = true; - expected_field_type = tcx.types.err; + final_field_type = tcx.types.err; + field_type_hint = tcx.types.err; if let Some(_) = variant.find_field_named(field.name.node) { let mut err = struct_span_err!(self.tcx.sess, field.name.span, @@ -3091,7 +3102,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Make sure to give a type to the field even if there's // an error, so we can continue typechecking - self.check_expr_coercable_to_type(&field.expr, expected_field_type); + let ty = self.check_expr_with_hint(&field.expr, field_type_hint); + self.demand_coerce(&field.expr, ty, final_field_type); } // Make sure the programmer specified correct number of fields. @@ -3201,6 +3213,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn check_expr_struct(&self, expr: &hir::Expr, + expected: Expectation<'tcx>, qpath: &hir::QPath, fields: &'gcx [hir::Field], base_expr: &'gcx Option>) -> Ty<'tcx> @@ -3219,7 +3232,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::QPath::TypeRelative(ref qself, _) => qself.span }; - self.check_expr_struct_fields(struct_ty, expr.id, path_span, variant, fields, + self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span, variant, fields, base_expr.is_none()); if let &Some(ref base_expr) = base_expr { self.check_expr_has_type(base_expr, struct_ty); @@ -3764,7 +3777,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } hir::ExprStruct(ref qpath, ref fields, ref base_expr) => { - self.check_expr_struct(expr, qpath, fields, base_expr) + self.check_expr_struct(expr, expected, qpath, fields, base_expr) } hir::ExprField(ref base, ref field) => { self.check_field(expr, lvalue_pref, &base, field) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index eff848be2b8b9..f3ea6c4467c40 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2241,11 +2241,11 @@ pub enum PathParameters { AngleBracketed { lifetimes: Vec, types: Vec, - bindings: Vec + bindings: Vec, }, Parenthesized { inputs: Vec, - output: Option + output: Option, } } @@ -2260,14 +2260,14 @@ impl Clean for hir::PathParameters { data.lifetimes.clean(cx) }, types: data.types.clean(cx), - bindings: data.bindings.clean(cx) + bindings: data.bindings.clean(cx), } } hir::ParenthesizedParameters(ref data) => { PathParameters::Parenthesized { inputs: data.inputs.clean(cx), - output: data.output.clean(cx) + output: data.output.clean(cx), } } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index fc5507d4d5559..a255ba0ad4edf 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -481,7 +481,7 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path, if is_not_debug { write!(w, "{:#}{:#}", HRef::new(did, &last.name), last.params)?; } else { - write!(w, "{:?}{:?}", HRef::new(did, &last.name), last.params)?; + write!(w, "{:?}{}", HRef::new(did, &last.name), last.params)?; } } else { if is_not_debug { @@ -507,7 +507,7 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path, } else { format!("{:?}", HRef::new(did, &last.name)) }; - write!(w, "{}{:?}", path, last.params)?; + write!(w, "{}{}", path, last.params)?; } } Ok(()) diff --git a/src/libstd/error.rs b/src/libstd/error.rs index e115263d2eb95..3d80120f6b2bd 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -216,6 +216,11 @@ impl<'a> From<&'a str> for Box { } } +#[stable(feature = "never_error", since = "1.18.0")] +impl Error for ! { + fn description(&self) -> &str { *self } +} + #[stable(feature = "rust1", since = "1.0.0")] impl Error for str::ParseBoolError { fn description(&self) -> &str { "failed to parse bool" } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 206a37b8e5db8..d01ed1e3fe63a 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -272,6 +272,7 @@ #![feature(linkage)] #![feature(macro_reexport)] #![feature(needs_panic_runtime)] +#![feature(never_type)] #![feature(num_bits_bytes)] #![feature(old_wrapping)] #![feature(on_unimplemented)] diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 35e4d9eb68aea..b75b3efda36c8 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -162,6 +162,12 @@ impl From for TokenStream { } } +impl From for TokenStream { + fn from(token: Token) -> TokenStream { + TokenTree::Token(DUMMY_SP, token).into() + } +} + impl> iter::FromIterator for TokenStream { fn from_iter>(iter: I) -> Self { TokenStream::concat(iter.into_iter().map(Into::into).collect::>()) diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index e89f48b4105d3..5ab786f40b933 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -9,6 +9,7 @@ // except according to those terms. #include "rustllvm.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/Instructions.h" @@ -594,7 +595,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable( const char *LinkageName, LLVMRustMetadataRef File, unsigned LineNo, LLVMRustMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V, LLVMRustMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) { - Constant *InitVal = cast(unwrap(V)); + llvm::GlobalVariable *InitVal = cast(unwrap(V)); #if LLVM_VERSION_GE(4, 0) llvm::DIExpression *InitExpr = nullptr; @@ -606,26 +607,21 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable( InitExpr = Builder->createConstantValueExpression( FPVal->getValueAPF().bitcastToAPInt().getZExtValue()); } -#endif -#if LLVM_VERSION_GE(4, 0) - return wrap(Builder->createGlobalVariableExpression( + llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression( + unwrapDI(Context), Name, LinkageName, + unwrapDI(File), LineNo, unwrapDI(Ty), IsLocalToUnit, + InitExpr, unwrapDIPtr(Decl), AlignInBits); + + InitVal->setMetadata("dbg", VarExpr); + + return wrap(VarExpr); #else return wrap(Builder->createGlobalVariable( -#endif unwrapDI(Context), Name, LinkageName, unwrapDI(File), LineNo, unwrapDI(Ty), IsLocalToUnit, -#if LLVM_VERSION_GE(4, 0) - InitExpr, -#else - InitVal, -#endif - unwrapDIPtr(Decl) -#if LLVM_VERSION_GE(4, 0) - , - AlignInBits + InitVal, unwrapDIPtr(Decl))); #endif - )); } extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable( diff --git a/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs index 2f94a440e72da..0433b95865ef8 100644 --- a/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs +++ b/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs @@ -49,9 +49,10 @@ fn cond(input: TokenStream) -> TokenStream { _ => false, }; conds.push(if is_else || input.peek().is_none() { - qquote!({ unquote rhs }) + quote!({ $rhs }) } else { - qquote!(if unquote(test.unwrap()) { unquote rhs } else) + let test = test.unwrap(); + quote!(if $test { $rhs } else) }); } diff --git a/src/test/run-pass-fulldeps/auxiliary/hello_macro.rs b/src/test/run-pass-fulldeps/auxiliary/hello_macro.rs index 91075276a3020..9522592a5e9e6 100644 --- a/src/test/run-pass-fulldeps/auxiliary/hello_macro.rs +++ b/src/test/run-pass-fulldeps/auxiliary/hello_macro.rs @@ -29,6 +29,11 @@ pub fn plugin_registrar(reg: &mut Registry) { // This macro is not very interesting, but it does contain delimited tokens with // no content - `()` and `{}` - which has caused problems in the past. +// Also, it tests that we can escape `$` via `$$`. fn hello(_: TokenStream) -> TokenStream { - qquote!({ fn hello() {} hello(); }) + quote!({ + fn hello() {} + macro_rules! m { ($$($$t:tt)*) => { $$($$t)* } } + m!(hello()); + }) } 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 612c199e8281a..0e37a7a5dcce2 100644 --- a/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs +++ b/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs @@ -34,21 +34,21 @@ pub fn plugin_registrar(reg: &mut Registry) { } fn attr_tru(_attr: TokenStream, _item: TokenStream) -> TokenStream { - qquote!(fn f1() -> bool { true }) + quote!(fn f1() -> bool { true }) } fn attr_identity(_attr: TokenStream, item: TokenStream) -> TokenStream { - qquote!(unquote item) + quote!($item) } fn tru(_ts: TokenStream) -> TokenStream { - qquote!(true) + quote!(true) } fn ret_tru(_ts: TokenStream) -> TokenStream { - qquote!(return true;) + quote!(return true;) } fn identity(ts: TokenStream) -> TokenStream { - qquote!(unquote ts) + quote!($ts) } diff --git a/src/test/run-pass-fulldeps/macro-quote-1.rs b/src/test/run-pass-fulldeps/macro-quote-1.rs index 57b6c3f0adb89..01b0ed802354c 100644 --- a/src/test/run-pass-fulldeps/macro-quote-1.rs +++ b/src/test/run-pass-fulldeps/macro-quote-1.rs @@ -22,6 +22,6 @@ use syntax::parse::token; use syntax::tokenstream::TokenTree; fn main() { - let true_tok = TokenTree::Token(syntax_pos::DUMMY_SP, token::Ident(Ident::from_str("true"))); - assert!(qquote!(true).eq_unspanned(&true_tok.into())); + let true_tok = token::Ident(Ident::from_str("true")); + assert!(quote!(true).eq_unspanned(&true_tok.into())); } diff --git a/src/test/run-pass-fulldeps/macro-quote-empty-delims.rs b/src/test/run-pass-fulldeps/macro-quote-test.rs similarity index 100% rename from src/test/run-pass-fulldeps/macro-quote-empty-delims.rs rename to src/test/run-pass-fulldeps/macro-quote-test.rs diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs index 2a7a593d26800..cef2f879f9cd7 100644 --- a/src/test/run-pass/ifmt.rs +++ b/src/test/run-pass/ifmt.rs @@ -160,6 +160,34 @@ pub fn main() { t!(format!("{:?}", -0.0), "-0"); t!(format!("{:?}", 0.0), "0"); + // sign aware zero padding + t!(format!("{:<3}", 1), "1 "); + t!(format!("{:>3}", 1), " 1"); + t!(format!("{:^3}", 1), " 1 "); + t!(format!("{:03}", 1), "001"); + t!(format!("{:<03}", 1), "001"); + t!(format!("{:>03}", 1), "001"); + t!(format!("{:^03}", 1), "001"); + t!(format!("{:+03}", 1), "+01"); + t!(format!("{:<+03}", 1), "+01"); + t!(format!("{:>+03}", 1), "+01"); + t!(format!("{:^+03}", 1), "+01"); + t!(format!("{:#05x}", 1), "0x001"); + t!(format!("{:<#05x}", 1), "0x001"); + t!(format!("{:>#05x}", 1), "0x001"); + t!(format!("{:^#05x}", 1), "0x001"); + t!(format!("{:05}", 1.2), "001.2"); + t!(format!("{:<05}", 1.2), "001.2"); + t!(format!("{:>05}", 1.2), "001.2"); + t!(format!("{:^05}", 1.2), "001.2"); + t!(format!("{:05}", -1.2), "-01.2"); + t!(format!("{:<05}", -1.2), "-01.2"); + t!(format!("{:>05}", -1.2), "-01.2"); + t!(format!("{:^05}", -1.2), "-01.2"); + t!(format!("{:+05}", 1.2), "+01.2"); + t!(format!("{:<+05}", 1.2), "+01.2"); + t!(format!("{:>+05}", 1.2), "+01.2"); + t!(format!("{:^+05}", 1.2), "+01.2"); // Ergonomic format_args! t!(format!("{0:x} {0:X}", 15), "f F"); diff --git a/src/test/run-pass/issue-31260.rs b/src/test/run-pass/issue-31260.rs new file mode 100644 index 0000000000000..e771fc7464d00 --- /dev/null +++ b/src/test/run-pass/issue-31260.rs @@ -0,0 +1,20 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub struct Struct { + pub field: K, +} + +// Partial fix for #31260, doesn't work without {...}. +static STRUCT: Struct<&'static [u8]> = Struct { + field: {&[1]} +}; + +fn main() {} diff --git a/src/test/rustdoc/const-doc.rs b/src/test/rustdoc/const-doc.rs new file mode 100644 index 0000000000000..9f70fe43175b9 --- /dev/null +++ b/src/test/rustdoc/const-doc.rs @@ -0,0 +1,31 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(associated_consts)] + +use std::marker::PhantomData; + +pub struct Foo<'a> { + f: PhantomData<&'a u32>, +} + +pub struct ContentType { + pub ttype: Foo<'static>, + pub subtype: Foo<'static>, + pub params: Option>, +} + +impl ContentType { + // @has const_doc/struct.ContentType.html + // @has - '//*[@class="docblock"]' 'Any: ContentType = ContentType{ttype: Foo{f: ' + pub const Any: ContentType = ContentType { ttype: Foo { f: PhantomData, }, + subtype: Foo { f: PhantomData, }, + params: None, }; +}