Auto merge of #40659 - frewsxcv:rollup, r=frewsxcv

Rollup of 9 pull requests

- Successful merges: #40241, #40281, #40398, #40521, #40532, #40554, #40566, #40581, #40587
- Failed merges:
This commit is contained in:
bors 2017-03-20 08:31:16 +00:00
commit 244f893ed7
37 changed files with 905 additions and 941 deletions

90
src/Cargo.lock generated
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1238,6 +1238,15 @@ extern "rust-intrinsic" {
/// undefined behavior where y = 0 or x = `T::min_value()` and y = -1
pub fn unchecked_rem<T>(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<T>(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<T>(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,

View File

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

View File

@ -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!(); }
//! 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::<TokenStream>();
//! 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)
//! });
//! }
//!
//! 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)) } })
//! }
//! 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)));
}

View File

@ -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<tokenstream::Cursor>);
struct Quoter(iter::Peekable<tokenstream::Cursor>);
impl Iterator for Quote {
impl Iterator for Quoter {
type Item = TokenStream;
fn next(&mut self) -> Option<TokenStream> {
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::<TokenStream>();
let quoted = Quoter(self.trees().peekable()).collect::<TokenStream>();
quote!([(unquote quoted)].iter().cloned().collect::<::syntax::tokenstream::TokenStream>())
}
}

View File

@ -12,5 +12,8 @@ crate-type = ["dylib"]
log = { path = "../liblog" }
rustc = { path = "../librustc" }
syntax = { path = "../libsyntax" }
serialize = { path = "../libserialize" }
syntax_pos = { path = "../libsyntax_pos" }
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"

View File

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

View File

@ -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<DefId>,
}
#[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<TypeRefData>,
}
#[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<Attribute>,
}
#[derive(Debug, RustcEncodable)]
#[derive(Debug)]
pub struct StructVariantData {
pub span: Span,
pub name: String,
@ -317,7 +311,7 @@ pub struct StructVariantData {
pub attributes: Vec<Attribute>,
}
#[derive(Debug, RustcEncodable)]
#[derive(Debug)]
pub struct TraitData {
pub span: Span,
pub id: NodeId,
@ -332,7 +326,7 @@ pub struct TraitData {
pub attributes: Vec<Attribute>,
}
#[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<Attribute>,
}
#[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,

View File

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

View File

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

View File

@ -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,43 +38,21 @@ 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,
}
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);
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,
}
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),
}
}
/// Represent an arbitrary attribute on a code element
#[derive(Clone, Debug, RustcEncodable)]
pub struct Attribute {
value: String,
span: SpanData,
}
impl Lower for Vec<ast::Attribute> {
type Target = Vec<Attribute>;
@ -91,20 +72,12 @@ impl Lower for Vec<ast::Attribute> {
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<data::ExternalCrateData>,
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,

View File

@ -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<CratePreludeData>,
imports: Vec<Import>,
defs: Vec<Def>,
relations: Vec<Relation>,
// 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<DefId> 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<UseData> for Option<Import> {
fn from(data: UseData) -> Option<Import> {
match data.visibility {
impl Into<Option<Import>> for UseData {
fn into(self) -> Option<Import> {
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<UseGlobData> for Option<Import> {
fn from(data: UseGlobData) -> Option<Import> {
match data.visibility {
impl Into<Option<Import>> for UseGlobData {
fn into(self) -> Option<Import> {
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<Id>,
children: Vec<Id>,
decl_id: Option<Id>,
docs: String,
sig: Option<JsonSignature>,
}
#[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<EnumData> for Option<Def> {
fn from(data: EnumData) -> Option<Def> {
match data.visibility {
impl Into<Option<Def>> for EnumData {
fn into(self) -> Option<Def> {
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<TupleVariantData> for Option<Def> {
fn from(data: TupleVariantData) -> Option<Def> {
impl Into<Option<Def>> for TupleVariantData {
fn into(self) -> Option<Def> {
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<StructVariantData> for Option<Def> {
fn from(data: StructVariantData) -> Option<Def> {
impl Into<Option<Def>> for StructVariantData {
fn into(self) -> Option<Def> {
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<StructData> for Option<Def> {
fn from(data: StructData) -> Option<Def> {
match data.visibility {
impl Into<Option<Def>> for StructData {
fn into(self) -> Option<Def> {
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<TraitData> for Option<Def> {
fn from(data: TraitData) -> Option<Def> {
match data.visibility {
impl Into<Option<Def>> for TraitData {
fn into(self) -> Option<Def> {
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<FunctionData> for Option<Def> {
fn from(data: FunctionData) -> Option<Def> {
match data.visibility {
impl Into<Option<Def>> for FunctionData {
fn into(self) -> Option<Def> {
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<MethodData> for Option<Def> {
fn from(data: MethodData) -> Option<Def> {
match data.visibility {
impl Into<Option<Def>> for MethodData {
fn into(self) -> Option<Def> {
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<MacroData> for Option<Def> {
fn from(data: MacroData) -> Option<Def> {
impl Into<Option<Def>> for MacroData {
fn into(self) -> Option<Def> {
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<ModData> for Option<Def> {
fn from(data:ModData) -> Option<Def> {
match data.visibility {
impl Into<Option<Def>> for ModData {
fn into(self) -> Option<Def> {
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<TypeDefData> for Option<Def> {
fn from(data: TypeDefData) -> Option<Def> {
match data.visibility {
impl Into<Option<Def>> for TypeDefData {
fn into(self) -> Option<Def> {
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<VariableData> for Option<Def> {
fn from(data: VariableData) -> Option<Def> {
match data.visibility {
impl Into<Option<Def>> for VariableData {
fn into(self) -> Option<Def> {
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<ImplData> 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<InheritanceData> 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<JsonSigElement>,
refs: Vec<JsonSigElement>,
}
impl From<Signature> 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<SigElement> for JsonSigElement {
fn from(data: SigElement) -> JsonSigElement {
JsonSigElement {
id: From::from(data.id),
start: data.start,
end: data.end,
}
}
}

View File

@ -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<CratePreludeData>,
imports: Vec<Import>,
defs: Vec<Def>,
refs: Vec<Ref>,
macro_refs: Vec<MacroRef>,
relations: Vec<Relation>,
}
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<DefId> 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<Id>,
span: SpanData,
name: String,
value: String,
}
#[derive(Debug, RustcEncodable)]
enum ImportKind {
ExternCrate,
Use,
GlobUse,
}
impl From<ExternCrateData> for Import {
fn from(data: ExternCrateData) -> Import {
impl Into<Import> 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<UseData> for Import {
fn from(data: UseData) -> Import {
impl Into<Import> 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<UseGlobData> for Import {
fn from(data: UseGlobData) -> Import {
impl Into<Import> 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<Id>,
decl_id: Option<Id>,
docs: String,
sig: Option<JsonSignature>,
attributes: Vec<Attribute>,
}
#[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<EnumData> for Def {
fn from(data: EnumData) -> Def {
impl Into<Def> 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<TupleVariantData> for Def {
fn from(data: TupleVariantData) -> Def {
impl Into<Def> 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<StructVariantData> for Def {
fn from(data: StructVariantData) -> Def {
impl Into<Def> 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<StructData> for Def {
fn from(data: StructData) -> Def {
impl Into<Def> 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<TraitData> for Def {
fn from(data: TraitData) -> Def {
impl Into<Def> 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<FunctionData> for Def {
fn from(data: FunctionData) -> Def {
impl Into<Def> 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<MethodData> for Def {
fn from(data: MethodData) -> Def {
impl Into<Def> 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<MacroData> for Def {
fn from(data: MacroData) -> Def {
impl Into<Def> 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<TypeDefData> for Def {
fn from(data: TypeDefData) -> Def {
impl Into<Def> 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<VariableData> for Def {
fn from(data: VariableData) -> Def {
impl Into<Def> 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<FunctionRefData> for Ref {
fn from(data: FunctionRefData) -> Ref {
impl Into<Ref> 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<FunctionCallData> for Ref {
fn from(data: FunctionCallData) -> Ref {
impl Into<Ref> 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<MethodCallData> for Ref {
fn from(data: MethodCallData) -> Ref {
impl Into<Ref> 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<ModRefData> for Ref {
fn from(data: ModRefData) -> Ref {
impl Into<Ref> 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<TypeRefData> for Ref {
fn from(data: TypeRefData) -> Ref {
impl Into<Ref> 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<VariableRefData> for Ref {
fn from(data: VariableRefData) -> Ref {
impl Into<Ref> 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<MacroUseData> for MacroRef {
fn from(data: MacroUseData) -> MacroRef {
impl Into<MacroRef> 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<ImplData> for Relation {
fn from(data: ImplData) -> Relation {
impl Into<Relation> 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<InheritanceData> for Relation {
fn from(data: InheritanceData) -> Relation {
impl Into<Relation> 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<JsonSigElement>,
refs: Vec<JsonSigElement>,
}
impl From<Signature> 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<Signature> 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<SigElement> for JsonSigElement {
fn from(data: SigElement) -> JsonSigElement {
JsonSigElement {
id: From::from(data.id),
start: data.start,
end: data.end,
impl Into<SigElement> for data::SigElement {
fn into(self) -> SigElement {
SigElement {
id: id_from_def_id(self.id),
start: self.start,
end: self.end,
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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<Ty<'tcx>> {
/// 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<Ty<'tcx>> {
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<P<hir::Expr>>) -> 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)

View File

@ -2241,11 +2241,11 @@ pub enum PathParameters {
AngleBracketed {
lifetimes: Vec<Lifetime>,
types: Vec<Type>,
bindings: Vec<TypeBinding>
bindings: Vec<TypeBinding>,
},
Parenthesized {
inputs: Vec<Type>,
output: Option<Type>
output: Option<Type>,
}
}
@ -2260,14 +2260,14 @@ impl Clean<PathParameters> 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),
}
}
}

View File

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

View File

@ -216,6 +216,11 @@ impl<'a> From<&'a str> for Box<Error> {
}
}
#[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" }

View File

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

View File

@ -162,6 +162,12 @@ impl From<TokenTree> for TokenStream {
}
}
impl From<Token> for TokenStream {
fn from(token: Token) -> TokenStream {
TokenTree::Token(DUMMY_SP, token).into()
}
}
impl<T: Into<TokenStream>> iter::FromIterator<T> for TokenStream {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
TokenStream::concat(iter.into_iter().map(Into::into).collect::<Vec<_>>())

View File

@ -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<Constant>(unwrap(V));
llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(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(
#else
return wrap(Builder->createGlobalVariable(
#endif
llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
unwrapDI<DIDescriptor>(Context), Name, LinkageName,
unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
#if LLVM_VERSION_GE(4, 0)
InitExpr,
InitExpr, unwrapDIPtr<MDNode>(Decl), AlignInBits);
InitVal->setMetadata("dbg", VarExpr);
return wrap(VarExpr);
#else
InitVal,
return wrap(Builder->createGlobalVariable(
unwrapDI<DIDescriptor>(Context), Name, LinkageName,
unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
InitVal, unwrapDIPtr<MDNode>(Decl)));
#endif
unwrapDIPtr<MDNode>(Decl)
#if LLVM_VERSION_GE(4, 0)
,
AlignInBits
#endif
));
}
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub struct Struct<K: 'static> {
pub field: K,
}
// Partial fix for #31260, doesn't work without {...}.
static STRUCT: Struct<&'static [u8]> = Struct {
field: {&[1]}
};
fn main() {}

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(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<Foo<'static>>,
}
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, };
}