diff --git a/src/Cargo.lock b/src/Cargo.lock index 7f532a8fef7d9..92ab670600b4e 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -66,6 +66,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "arena" version = "0.0.0" +dependencies = [ + "rustc_data_structures 0.0.0", +] [[package]] name = "atty" @@ -117,7 +120,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitflags" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -126,14 +129,14 @@ version = "0.0.0" dependencies = [ "build_helper 0.1.0", "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cmake 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -151,8 +154,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "build-manifest" version = "0.1.0" dependencies = [ - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -199,8 +202,8 @@ dependencies = [ "same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -217,8 +220,8 @@ name = "cargo_metadata" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -276,10 +279,10 @@ dependencies = [ "clippy_lints 0.0.166", "compiletest_rs 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "duct 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -292,14 +295,14 @@ version = "0.0.166" dependencies = [ "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)", "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -307,7 +310,7 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -395,8 +398,8 @@ version = "0.13.0" dependencies = [ "curl 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -431,7 +434,7 @@ dependencies = [ "cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "procedural-masquerade 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "procedural-masquerade 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -442,7 +445,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "procedural-masquerade 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "procedural-masquerade 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -510,10 +513,10 @@ name = "docopt" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -736,12 +739,12 @@ name = "handlebars" version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -804,7 +807,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -832,7 +835,7 @@ dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -868,8 +871,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -899,8 +902,8 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -908,7 +911,7 @@ dependencies = [ [[package]] name = "lazy_static" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -934,7 +937,7 @@ version = "0.6.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cmake 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "curl-sys 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -948,7 +951,7 @@ name = "libssh2-sys" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cmake 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1018,13 +1021,13 @@ dependencies = [ "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1187,7 +1190,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1244,9 +1247,30 @@ dependencies = [ "unwind 0.0.0", ] +[[package]] +name = "parking_lot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.2.6" +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.33 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "percent-encoding" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1309,7 +1333,7 @@ dependencies = [ [[package]] name = "procedural-masquerade" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1369,7 +1393,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clap 2.27.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1456,7 +1480,7 @@ dependencies = [ "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "languageserver-types 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "rls-analysis 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1465,8 +1489,8 @@ dependencies = [ "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-vfs 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustfmt-nightly 0.2.15", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1490,8 +1514,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1505,8 +1529,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1531,7 +1555,7 @@ name = "rustc" version = "0.0.0" dependencies = [ "arena 0.0.0", - "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "fmt_macros 0.0.0", "graphviz 0.0.0", @@ -1579,7 +1603,7 @@ dependencies = [ name = "rustc_apfloat" version = "0.0.0" dependencies = [ - "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_cratesio_shim 0.0.0", ] @@ -1590,7 +1614,7 @@ dependencies = [ "alloc 0.0.0", "alloc_system 0.0.0", "build_helper 0.1.0", - "cmake 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -1646,7 +1670,7 @@ dependencies = [ name = "rustc_cratesio_shim" version = "0.0.0" dependencies = [ - "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1654,6 +1678,8 @@ name = "rustc_data_structures" version = "0.0.0" dependencies = [ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "serialize 0.0.0", ] @@ -1730,7 +1756,7 @@ dependencies = [ name = "rustc_llvm" version = "0.0.0" dependencies = [ - "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "build_helper 0.1.0", "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_cratesio_shim 0.0.0", @@ -1743,7 +1769,7 @@ dependencies = [ "alloc 0.0.0", "alloc_system 0.0.0", "build_helper 0.1.0", - "cmake 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -1769,7 +1795,7 @@ dependencies = [ name = "rustc_mir" version = "0.0.0" dependencies = [ - "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "graphviz 0.0.0", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", @@ -1789,7 +1815,7 @@ dependencies = [ "alloc 0.0.0", "alloc_system 0.0.0", "build_helper 0.1.0", - "cmake 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -1864,7 +1890,7 @@ dependencies = [ name = "rustc_trans" version = "0.0.0" dependencies = [ - "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1910,7 +1936,7 @@ dependencies = [ "alloc 0.0.0", "alloc_system 0.0.0", "build_helper 0.1.0", - "cmake 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -1962,10 +1988,10 @@ dependencies = [ "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "strings 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "strings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2020,7 +2046,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2030,12 +2056,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2057,7 +2083,7 @@ name = "serde_ignored" version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2068,7 +2094,7 @@ dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2100,6 +2126,11 @@ name = "smallvec" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "smallvec" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "socket2" version = "0.2.4" @@ -2153,10 +2184,10 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2179,7 +2210,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "strings" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2212,7 +2243,7 @@ dependencies = [ name = "syntax" version = "0.0.0" dependencies = [ - "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_cratesio_shim 0.0.0", "rustc_data_structures 0.0.0", @@ -2236,6 +2267,7 @@ dependencies = [ name = "syntax_pos" version = "0.0.0" dependencies = [ + "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_data_structures 0.0.0", "serialize 0.0.0", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2374,7 +2406,7 @@ name = "thread_local" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2395,7 +2427,7 @@ name = "toml" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2469,7 +2501,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2477,7 +2509,7 @@ name = "url_serde" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2597,13 +2629,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" -"checksum bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5cde24d1b2e2216a726368b2363a273739c91f4e3eb4e0dd12d672d396ad989" +"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32" "checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b" "checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum clap 2.27.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b8c532887f1a292d17de05ae858a8fe50a301e196f9ef0ddb7ccd0d1d00f180" -"checksum cmake 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "357c07e7a1fc95732793c1edb5901e1a1f305cfcf63a90eb12dbd22bdb6b789d" +"checksum cmake 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)" = "9b0ec063cbc2034e27f7166d04aa7aa1b9ed85b6c7c2414fb68aff20d1ebf604" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" "checksum compiletest_rs 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2741d378feb7a434dba54228c89a70b4e427fee521de67cdda3750b8a0265f5a" @@ -2659,7 +2691,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kuchiki 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ef2ea4f2f7883cd7c6772b06c14abca01a2cc1f75c426cebffcf6b3b925ef9fc" "checksum languageserver-types 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d52e477b23bf52cd3ca0f9fc6c5d14be954eec97e3b9cdfbd962d911bd533caf" -"checksum lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9e5e58fa1a4c3b915a561a78a22ee0cac6ab97dca2504428bc1cb074375f8d5" +"checksum lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "236eb37a62591d4a41a89b7763d7de3e06ca02d5ab2815446a8bae5d2f8c2d57" "checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" "checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2" "checksum libgit2-sys 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "6f74b4959cef96898f5123148724fc7dee043b9a6b99f219d948851bfbe53cb2" @@ -2692,7 +2724,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum openssl-sys 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)" = "0ad395f1cee51b64a8d07cc8063498dc7554db62d5f3ca87a67f4eed2791d0c8" "checksum os_pipe 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "998bfbb3042e715190fe2a41abfa047d7e8cb81374d2977d7f100eacd8619cb1" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" -"checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356" +"checksum parking_lot 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9517dca2f725f6fdefc25bbd08837f76f525fb513eeb2383d643bed8339053ed" +"checksum parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f610cb9664da38e417ea3225f23051f589851999535290e077939838ab7a595" +"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8" "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" @@ -2700,7 +2734,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2" "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" -"checksum procedural-masquerade 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9ae21842e88415394f6b6fccf1f4af4c98a5bfb3eab92188f2e83409cda0c995" +"checksum procedural-masquerade 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1bcafee1590f81acb329ae45ec627b318123f085153913620316ae9a144b2a" "checksum psapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "abcd5d1a07d360e29727f757a9decb3ce8bc6e0efa8969cfaad669a8317a2478" "checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b" "checksum pulldown-cmark 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a656fdb8b6848f896df5e478a0eb9083681663e37dcb77dd16981ff65329fe8b" @@ -2729,8 +2763,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" "checksum semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bee2bc909ab2d8d60dab26e8cad85b25d795b14603a0dcb627b78b9d30b6454b" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "0c9cab69e16835717c9b8bd13c29f92b6aa34fe32ce2866b1ab481cf2da8442a" -"checksum serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3bdafe3e71710131a919735916caa5b18c2754ad0d33d8ae5d586ccc804a403e" +"checksum serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "5a2b181dd2b4a6353e828e44807269a761d3ecbc388a1f5ed3998ea69a516d9c" +"checksum serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "31ce3c16ec18abb97d977f75880986549213b0c18f2695eda8b31eadc96eda4a" "checksum serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32f1926285523b2db55df263d2aa4eb69ddcfa7a7eade6430323637866b513ab" "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142" "checksum serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e4586746d1974a030c48919731ecffd0ed28d0c40749d0d18d43b3a7d6c9b20e" @@ -2738,12 +2772,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5cc96481d54583947bfe88bf30c23d53f883c6cd0145368b69989d97b84ef8" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" "checksum smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f8266519bc1d17d0b5b16f6c21295625d562841c708f6376f49028a43e9c11e" +"checksum smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4f357e8cd37bf8822e1b964e96fd39e2cb5a0424f8aaa284ccaccc2162411c" "checksum socket2 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b4896961171cd3317c7e9603d88f379f8c6e45342212235d356496680c68fd" "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" "checksum string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "413fc7852aeeb5472f1986ef755f561ddf0c789d3d796e65f0b6fe293ecd4ef8" "checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7" "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" -"checksum strings 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da75d8bf2c4d210d63dd09581a041b036001f9f6e03d9b151dbff810fb7ba26a" +"checksum strings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa481ee1bc42fc3df8195f91f7cb43cf8f2b71b48bac40bf5381cfaf7e481f3c" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" diff --git a/src/libarena/Cargo.toml b/src/libarena/Cargo.toml index b53c0a2f48bf7..e2af67dd92861 100644 --- a/src/libarena/Cargo.toml +++ b/src/libarena/Cargo.toml @@ -7,3 +7,6 @@ version = "0.0.0" name = "arena" path = "lib.rs" crate-type = ["dylib"] + +[dependencies] +rustc_data_structures = { path = "../librustc_data_structures" } \ No newline at end of file diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 2be7b1bc2e17c..a23fc118bebdf 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -33,6 +33,9 @@ #![allow(deprecated)] extern crate alloc; +extern crate rustc_data_structures; + +use rustc_data_structures::lock::Lock; use std::cell::{Cell, RefCell}; use std::cmp; @@ -46,6 +49,10 @@ use alloc::raw_vec::RawVec; /// An arena that can hold objects of only one type. pub struct TypedArena { + lock: Lock>, +} + +struct TypedArenaInner { /// A pointer to the next object to be allocated. ptr: Cell<*mut T>, @@ -109,38 +116,102 @@ impl TypedArenaChunk { const PAGE: usize = 4096; +impl TypedArenaInner { + /// Grows the arena. + #[inline(never)] + #[cold] + fn grow(&self, n: usize) { + unsafe { + let mut chunks = self.chunks.borrow_mut(); + let (chunk, mut new_capacity); + if let Some(last_chunk) = chunks.last_mut() { + let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize; + let currently_used_cap = used_bytes / mem::size_of::(); + if last_chunk.storage.reserve_in_place(currently_used_cap, n) { + self.end.set(last_chunk.end()); + return; + } else { + new_capacity = last_chunk.storage.cap(); + loop { + new_capacity = new_capacity.checked_mul(2).unwrap(); + if new_capacity >= currently_used_cap + n { + break; + } + } + } + } else { + let elem_size = cmp::max(1, mem::size_of::()); + new_capacity = cmp::max(n, PAGE / elem_size); + } + chunk = TypedArenaChunk::::new(new_capacity); + self.ptr.set(chunk.start()); + self.end.set(chunk.end()); + chunks.push(chunk); + } + } + + // Drops the contents of the last chunk. The last chunk is partially empty, unlike all other + // chunks. + fn clear_last_chunk(&self, last_chunk: &mut TypedArenaChunk) { + // Determine how much was filled. + let start = last_chunk.start() as usize; + // We obtain the value of the pointer to the first uninitialized element. + let end = self.ptr.get() as usize; + // We then calculate the number of elements to be dropped in the last chunk, + // which is the filled area's length. + let diff = if mem::size_of::() == 0 { + // `T` is ZST. It can't have a drop flag, so the value here doesn't matter. We get + // the number of zero-sized values in the last and only chunk, just out of caution. + // Recall that `end` was incremented for each allocated value. + end - start + } else { + (end - start) / mem::size_of::() + }; + // Pass that to the `destroy` method. + unsafe { + last_chunk.destroy(diff); + } + // Reset the chunk. + self.ptr.set(last_chunk.start()); + } +} + impl TypedArena { /// Creates a new `TypedArena`. #[inline] pub fn new() -> TypedArena { TypedArena { - // We set both `ptr` and `end` to 0 so that the first call to - // alloc() will trigger a grow(). - ptr: Cell::new(0 as *mut T), - end: Cell::new(0 as *mut T), - chunks: RefCell::new(vec![]), - _own: PhantomData, + lock: Lock::new(TypedArenaInner { + // We set both `ptr` and `end` to 0 so that the first call to + // alloc() will trigger a grow(). + ptr: Cell::new(0 as *mut T), + end: Cell::new(0 as *mut T), + chunks: RefCell::new(vec![]), + _own: PhantomData, + }) } } /// Allocates an object in the `TypedArena`, returning a reference to it. #[inline] pub fn alloc(&self, object: T) -> &mut T { - if self.ptr == self.end { - self.grow(1) + let this = self.lock.lock(); + + if this.ptr == this.end { + this.grow(1) } unsafe { if mem::size_of::() == 0 { - self.ptr.set(intrinsics::arith_offset(self.ptr.get() as *mut u8, 1) as *mut T); + this.ptr.set(intrinsics::arith_offset(this.ptr.get() as *mut u8, 1) as *mut T); let ptr = mem::align_of::() as *mut T; // Don't drop the object. This `write` is equivalent to `forget`. ptr::write(ptr, object); &mut *ptr } else { - let ptr = self.ptr.get(); + let ptr = this.ptr.get(); // Advance the pointer. - self.ptr.set(self.ptr.get().offset(1)); + this.ptr.set(this.ptr.get().offset(1)); // Write into uninitialized memory. ptr::write(ptr, object); &mut *ptr @@ -160,61 +231,32 @@ impl TypedArena { assert!(mem::size_of::() != 0); assert!(slice.len() != 0); - let available_capacity_bytes = self.end.get() as usize - self.ptr.get() as usize; + let this = self.lock.lock(); + + let available_capacity_bytes = this.end.get() as usize - this.ptr.get() as usize; let at_least_bytes = slice.len() * mem::size_of::(); if available_capacity_bytes < at_least_bytes { - self.grow(slice.len()); + this.grow(slice.len()); } unsafe { - let start_ptr = self.ptr.get(); + let start_ptr = this.ptr.get(); let arena_slice = slice::from_raw_parts_mut(start_ptr, slice.len()); - self.ptr.set(start_ptr.offset(arena_slice.len() as isize)); + this.ptr.set(start_ptr.offset(arena_slice.len() as isize)); arena_slice.copy_from_slice(slice); arena_slice } } - /// Grows the arena. - #[inline(never)] - #[cold] - fn grow(&self, n: usize) { - unsafe { - let mut chunks = self.chunks.borrow_mut(); - let (chunk, mut new_capacity); - if let Some(last_chunk) = chunks.last_mut() { - let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize; - let currently_used_cap = used_bytes / mem::size_of::(); - if last_chunk.storage.reserve_in_place(currently_used_cap, n) { - self.end.set(last_chunk.end()); - return; - } else { - new_capacity = last_chunk.storage.cap(); - loop { - new_capacity = new_capacity.checked_mul(2).unwrap(); - if new_capacity >= currently_used_cap + n { - break; - } - } - } - } else { - let elem_size = cmp::max(1, mem::size_of::()); - new_capacity = cmp::max(n, PAGE / elem_size); - } - chunk = TypedArenaChunk::::new(new_capacity); - self.ptr.set(chunk.start()); - self.end.set(chunk.end()); - chunks.push(chunk); - } - } - /// Clears the arena. Deallocates all but the longest chunk which may be reused. pub fn clear(&mut self) { + let this = self.lock.lock(); + unsafe { // Clear the last chunk, which is partially filled. - let mut chunks_borrow = self.chunks.borrow_mut(); + let mut chunks_borrow = this.chunks.borrow_mut(); if let Some(mut last_chunk) = chunks_borrow.pop() { - self.clear_last_chunk(&mut last_chunk); + this.clear_last_chunk(&mut last_chunk); // If `T` is ZST, code below has no effect. for mut chunk in chunks_borrow.drain(..) { let cap = chunk.storage.cap(); @@ -224,41 +266,18 @@ impl TypedArena { } } } - - // Drops the contents of the last chunk. The last chunk is partially empty, unlike all other - // chunks. - fn clear_last_chunk(&self, last_chunk: &mut TypedArenaChunk) { - // Determine how much was filled. - let start = last_chunk.start() as usize; - // We obtain the value of the pointer to the first uninitialized element. - let end = self.ptr.get() as usize; - // We then calculate the number of elements to be dropped in the last chunk, - // which is the filled area's length. - let diff = if mem::size_of::() == 0 { - // `T` is ZST. It can't have a drop flag, so the value here doesn't matter. We get - // the number of zero-sized values in the last and only chunk, just out of caution. - // Recall that `end` was incremented for each allocated value. - end - start - } else { - (end - start) / mem::size_of::() - }; - // Pass that to the `destroy` method. - unsafe { - last_chunk.destroy(diff); - } - // Reset the chunk. - self.ptr.set(last_chunk.start()); - } } unsafe impl<#[may_dangle] T> Drop for TypedArena { fn drop(&mut self) { + let this = self.lock.get_mut(); + unsafe { // Determine how much was filled. - let mut chunks_borrow = self.chunks.borrow_mut(); + let mut chunks_borrow = this.chunks.borrow_mut(); if let Some(mut last_chunk) = chunks_borrow.pop() { // Drop the contents of the last chunk. - self.clear_last_chunk(&mut last_chunk); + this.clear_last_chunk(&mut last_chunk); // The last chunk will be dropped. Destroy all other chunks. for chunk in chunks_borrow.iter_mut() { let cap = chunk.storage.cap(); @@ -270,9 +289,13 @@ unsafe impl<#[may_dangle] T> Drop for TypedArena { } } -unsafe impl Send for TypedArena {} +unsafe impl Send for TypedArenaInner {} pub struct DroplessArena { + lock: Lock, +} + +struct DroplessArenaInner { /// A pointer to the next object to be allocated. ptr: Cell<*mut u8>, @@ -284,26 +307,9 @@ pub struct DroplessArena { chunks: RefCell>>, } -impl DroplessArena { - pub fn new() -> DroplessArena { - DroplessArena { - ptr: Cell::new(0 as *mut u8), - end: Cell::new(0 as *mut u8), - chunks: RefCell::new(vec![]), - } - } - - pub fn in_arena(&self, ptr: *const T) -> bool { - let ptr = ptr as *const u8 as *mut u8; - for chunk in &*self.chunks.borrow() { - if chunk.start() <= ptr && ptr < chunk.end() { - return true; - } - } - - false - } +unsafe impl Send for DroplessArenaInner {} +impl DroplessArenaInner { fn align_for(&self) { let align = mem::align_of::(); let final_address = ((self.ptr.get() as usize) + align - 1) & !(align - 1); @@ -341,6 +347,31 @@ impl DroplessArena { chunks.push(chunk); } } +} + +impl DroplessArena { + pub fn new() -> DroplessArena { + DroplessArena { + lock: Lock::new(DroplessArenaInner { + ptr: Cell::new(0 as *mut u8), + end: Cell::new(0 as *mut u8), + chunks: RefCell::new(vec![]), + }) + } + } + + pub fn in_arena(&self, ptr: *const T) -> bool { + let this = self.lock.lock(); + + let ptr = ptr as *const u8 as *mut u8; + for chunk in &*this.chunks.borrow() { + if chunk.start() <= ptr && ptr < chunk.end() { + return true; + } + } + + false + } #[inline] pub fn alloc(&self, object: T) -> &mut T { @@ -348,16 +379,18 @@ impl DroplessArena { assert!(!mem::needs_drop::()); assert!(mem::size_of::() != 0); - self.align_for::(); - let future_end = intrinsics::arith_offset(self.ptr.get(), mem::size_of::() as isize); - if (future_end as *mut u8) >= self.end.get() { - self.grow::(1) + let this = self.lock.lock(); + + this.align_for::(); + let future_end = intrinsics::arith_offset(this.ptr.get(), mem::size_of::() as isize); + if (future_end as *mut u8) >= this.end.get() { + this.grow::(1) } - let ptr = self.ptr.get(); + let ptr = this.ptr.get(); // Set the pointer past ourselves - self.ptr.set(intrinsics::arith_offset( - self.ptr.get(), mem::size_of::() as isize + this.ptr.set(intrinsics::arith_offset( + this.ptr.get(), mem::size_of::() as isize ) as *mut u8); // Write into uninitialized memory. ptr::write(ptr as *mut T, object); @@ -377,19 +410,22 @@ impl DroplessArena { assert!(!mem::needs_drop::()); assert!(mem::size_of::() != 0); assert!(slice.len() != 0); - self.align_for::(); + + let this = self.lock.lock(); + + this.align_for::(); let future_end = unsafe { - intrinsics::arith_offset(self.ptr.get(), (slice.len() * mem::size_of::()) as isize) + intrinsics::arith_offset(this.ptr.get(), (slice.len() * mem::size_of::()) as isize) }; - if (future_end as *mut u8) >= self.end.get() { - self.grow::(slice.len()); + if (future_end as *mut u8) >= this.end.get() { + this.grow::(slice.len()); } unsafe { - let arena_slice = slice::from_raw_parts_mut(self.ptr.get() as *mut T, slice.len()); - self.ptr.set(intrinsics::arith_offset( - self.ptr.get(), (slice.len() * mem::size_of::()) as isize + let arena_slice = slice::from_raw_parts_mut(this.ptr.get() as *mut T, slice.len()); + this.ptr.set(intrinsics::arith_offset( + this.ptr.get(), (slice.len() * mem::size_of::()) as isize ) as *mut u8); arena_slice.copy_from_slice(slice); arena_slice diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 8a400f3e6360e..6c4608c107b06 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -50,7 +50,7 @@ mod diagnostic; pub use diagnostic::{Diagnostic, Level}; use std::{ascii, fmt, iter}; -use std::rc::Rc; +use std::sync::Arc; use std::str::FromStr; use syntax::ast; @@ -274,7 +274,7 @@ pub struct LineColumn { #[unstable(feature = "proc_macro", issue = "38356")] #[derive(Clone)] pub struct SourceFile { - filemap: Rc, + filemap: Arc, } impl SourceFile { @@ -324,7 +324,7 @@ impl fmt::Debug for SourceFile { #[unstable(feature = "proc_macro", issue = "38356")] impl PartialEq for SourceFile { fn eq(&self, other: &Self) -> bool { - Rc::ptr_eq(&self.filemap, &other.filemap) + Arc::ptr_eq(&self.filemap, &other.filemap) } } diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 97ac1b256124d..7a9d01c970df2 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -13,10 +13,10 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHashingContextProvider}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; -use std::cell::{Ref, RefCell}; +use rustc_data_structures::lock::{RwLock, ReadGuard, Lock}; use std::env; use std::hash::Hash; -use std::rc::Rc; +use std::sync::Arc; use ty::TyCtxt; use util::common::{ProfileQueriesMsg, profq_msg}; @@ -32,7 +32,7 @@ use super::prev::PreviousDepGraph; #[derive(Clone)] pub struct DepGraph { - data: Option>, + data: Option>, // At the moment we are using DepNode as key here. In the future it might // be possible to use an IndexVec here. At the moment there @@ -41,7 +41,7 @@ pub struct DepGraph { // we need to have a dep-graph to generate DepNodeIndices. // - The architecture is still in flux and it's not clear what how to best // implement things. - fingerprints: Rc>> + fingerprints: Arc>> } @@ -71,50 +71,50 @@ struct DepGraphData { /// tracking. The `current` field is the dependency graph of only the /// current compilation session: We don't merge the previous dep-graph into /// current one anymore. - current: RefCell, + current: Lock, /// The dep-graph from the previous compilation session. It contains all /// nodes and edges as well as all fingerprints of nodes that have them. previous: PreviousDepGraph, - colors: RefCell>, + colors: Lock>, /// When we load, there may be `.o` files, cached mir, or other such /// things available to us. If we find that they are not dirty, we /// load the path to the file storing those work-products here into /// this map. We can later look for and extract that data. - previous_work_products: RefCell>, + previous_work_products: RwLock>, /// Work-products that we generate in this run. - work_products: RefCell>, + work_products: RwLock>, - dep_node_debug: RefCell>, + dep_node_debug: Lock>, // Used for testing, only populated when -Zquery-dep-graph is specified. - loaded_from_cache: RefCell>, + loaded_from_cache: Lock>, } impl DepGraph { pub fn new(prev_graph: PreviousDepGraph) -> DepGraph { DepGraph { - data: Some(Rc::new(DepGraphData { - previous_work_products: RefCell::new(FxHashMap()), - work_products: RefCell::new(FxHashMap()), - dep_node_debug: RefCell::new(FxHashMap()), - current: RefCell::new(CurrentDepGraph::new()), + data: Some(Arc::new(DepGraphData { + previous_work_products: RwLock::new(FxHashMap()), + work_products: RwLock::new(FxHashMap()), + dep_node_debug: Lock::new(FxHashMap()), + current: Lock::new(CurrentDepGraph::new()), previous: prev_graph, - colors: RefCell::new(FxHashMap()), - loaded_from_cache: RefCell::new(FxHashMap()), + colors: Lock::new(FxHashMap()), + loaded_from_cache: Lock::new(FxHashMap()), })), - fingerprints: Rc::new(RefCell::new(FxHashMap())), + fingerprints: Arc::new(Lock::new(FxHashMap())), } } pub fn new_disabled() -> DepGraph { DepGraph { data: None, - fingerprints: Rc::new(RefCell::new(FxHashMap())), + fingerprints: Arc::new(Lock::new(FxHashMap())), } } @@ -196,8 +196,8 @@ impl DepGraph { cx: C, arg: A, task: fn(C, A) -> R, - push: fn(&RefCell, DepNode), - pop: fn(&RefCell, DepNode) -> DepNodeIndex) + push: fn(&Lock, DepNode), + pop: fn(&Lock, DepNode) -> DepNodeIndex) -> (R, DepNodeIndex) where C: DepGraphSafe + StableHashingContextProvider, R: HashStable, @@ -378,13 +378,13 @@ impl DepGraph { /// Access the map of work-products created during this run. Only /// used during saving of the dep-graph. - pub fn work_products(&self) -> Ref> { + pub fn work_products(&self) -> ReadGuard> { self.data.as_ref().unwrap().work_products.borrow() } /// Access the map of work-products created during the cached run. Only /// used during saving of the dep-graph. - pub fn previous_work_products(&self) -> Ref> { + pub fn previous_work_products(&self) -> ReadGuard> { self.data.as_ref().unwrap().previous_work_products.borrow() } diff --git a/src/librustc/dep_graph/raii.rs b/src/librustc/dep_graph/raii.rs index 5728bcc7d2771..268bb39d25e42 100644 --- a/src/librustc/dep_graph/raii.rs +++ b/src/librustc/dep_graph/raii.rs @@ -10,14 +10,14 @@ use super::graph::CurrentDepGraph; -use std::cell::RefCell; +use rustc_data_structures::lock::Lock; pub struct IgnoreTask<'graph> { - graph: &'graph RefCell, + graph: &'graph Lock, } impl<'graph> IgnoreTask<'graph> { - pub(super) fn new(graph: &'graph RefCell) -> IgnoreTask<'graph> { + pub(super) fn new(graph: &'graph Lock) -> IgnoreTask<'graph> { graph.borrow_mut().push_ignore(); IgnoreTask { graph, diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 1b590c2b2c477..63897f5dcf2b8 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -29,9 +29,10 @@ use hir::print::Nested; use util::nodemap::{DefIdMap, FxHashMap}; use arena::TypedArena; -use std::cell::RefCell; use std::io; +use rustc_data_structures::lock::Lock; + pub mod blocks; mod collector; mod def_collector; @@ -255,7 +256,7 @@ pub struct Map<'hir> { definitions: &'hir Definitions, /// Bodies inlined from other crates are cached here. - inlined_bodies: RefCell>, + inlined_bodies: Lock>, /// The reverse mapping of `node_to_hir_id`. hir_to_node_id: FxHashMap, @@ -1078,7 +1079,7 @@ pub fn map_crate<'hir>(sess: &::session::Session, map, hir_to_node_id, definitions, - inlined_bodies: RefCell::new(DefIdMap()), + inlined_bodies: Lock::new(DefIdMap()), }; hir_id_validator::check_crate(&map); diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index a7206f5d420a5..7ab5e3a3ccc1e 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -212,6 +212,11 @@ pub struct Path { } impl Path { + #[allow(dead_code)] + fn dummy() { + ::rustc_data_structures::lock::assert_sync::(); + } + pub fn is_global(&self) -> bool { !self.segments.is_empty() && self.segments[0].name == keywords::CrateRoot.name() } @@ -1049,7 +1054,14 @@ pub struct Expr { pub attrs: ThinVec, pub hir_id: HirId, } - +/* +impl Expr { + #[allow(dead_code)] + fn dummy() { + ::rustc_data_structures::lock::assert_sync::(); + } +} +*/ impl fmt::Debug for Expr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "expr({}: {})", self.id, diff --git a/src/librustc/ich/caching_codemap_view.rs b/src/librustc/ich/caching_codemap_view.rs index e393459027859..f5e4155f5b976 100644 --- a/src/librustc/ich/caching_codemap_view.rs +++ b/src/librustc/ich/caching_codemap_view.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::rc::Rc; +use std::sync::Arc; use syntax::codemap::CodeMap; use syntax_pos::{BytePos, FileMap}; @@ -18,7 +18,7 @@ struct CacheEntry { line_number: usize, line_start: BytePos, line_end: BytePos, - file: Rc, + file: Arc, file_index: usize, } @@ -51,7 +51,7 @@ impl<'cm> CachingCodemapView<'cm> { pub fn byte_pos_to_line_and_col(&mut self, pos: BytePos) - -> Option<(Rc, usize, BytePos)> { + -> Option<(Arc, usize, BytePos)> { self.time_stamp += 1; // Check if the position is in one of the cached lines @@ -78,11 +78,9 @@ impl<'cm> CachingCodemapView<'cm> { // If the entry doesn't point to the correct file, fix it up if pos < cache_entry.file.start_pos || pos >= cache_entry.file.end_pos { let file_valid; - let files = self.codemap.files(); - - if files.len() > 0 { + if self.codemap.files().len() > 0 { let file_index = self.codemap.lookup_filemap_idx(pos); - let file = files[file_index].clone(); + let file = self.codemap.files()[file_index].clone(); if pos >= file.start_pos && pos < file.end_pos { cache_entry.file = file; diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 601e0316d4af9..81ae213e4f79f 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -26,6 +26,7 @@ use self::TargetLint::*; +use rustc_data_structures::lock::{RwLock, ReadGuard}; use rustc_back::slice; use lint::{EarlyLintPassObject, LateLintPassObject}; use lint::{Level, Lint, LintId, LintPass, LintBuffer}; @@ -38,7 +39,6 @@ use ty::{self, TyCtxt}; use util::nodemap::FxHashMap; use std::default::Default as StdDefault; -use std::cell::{Ref, RefCell}; use syntax::ast; use syntax_pos::{MultiSpan, Span}; use errors::DiagnosticBuilder; @@ -76,7 +76,7 @@ pub struct LintStore { pub struct LintSession<'a, PassObject> { /// Reference to the store of registered lints. - lints: Ref<'a, LintStore>, + lints: ReadGuard<'a, LintStore>, /// Trait objects for each lint pass. passes: Option>, @@ -316,7 +316,7 @@ impl<'a, PassObject: LintPassObject> LintSession<'a, PassObject> { /// Creates a new `LintSession`, by moving out the `LintStore`'s initial /// lint levels and pass objects. These can be restored using the `restore` /// method. - fn new(store: &'a RefCell) -> LintSession<'a, PassObject> { + fn new(store: &'a RwLock) -> LintSession<'a, PassObject> { let mut s = store.borrow_mut(); let passes = PassObject::take_passes(&mut *s); drop(s); @@ -327,7 +327,7 @@ impl<'a, PassObject: LintPassObject> LintSession<'a, PassObject> { } /// Restores the levels back to the original lint store. - fn restore(self, store: &RefCell) { + fn restore(self, store: &RwLock) { drop(self.lints); let mut s = store.borrow_mut(); PassObject::restore_passes(&mut *s, self.passes); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index d648099d74d36..18a902f5e26de 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -31,7 +31,7 @@ pub use self::Level::*; pub use self::LintSource::*; -use std::rc::Rc; +use std::sync::Arc; use errors::{DiagnosticBuilder, DiagnosticId}; use hir::def_id::{CrateNum, LOCAL_CRATE}; @@ -260,8 +260,8 @@ pub trait EarlyLintPass: LintPass { } /// A lint pass boxed up as a trait object. -pub type EarlyLintPassObject = Box; -pub type LateLintPassObject = Box LateLintPass<'a, 'tcx> + 'static>; +pub type EarlyLintPassObject = Box; +pub type LateLintPassObject = Box LateLintPass<'a, 'tcx> + Send + Sync + 'static>; /// Identifies a lint known to the compiler. #[derive(Clone, Copy, Debug)] @@ -482,7 +482,7 @@ pub fn struct_lint_level<'a>(sess: &'a Session, } fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum) - -> Rc + -> Arc { assert_eq!(cnum, LOCAL_CRATE); let mut builder = LintLevelMapBuilder { @@ -495,7 +495,7 @@ fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum) intravisit::walk_crate(builder, krate); }); - Rc::new(builder.levels.build_map()) + Arc::new(builder.levels.build_map()) } struct LintLevelMapBuilder<'a, 'tcx: 'a> { diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 628538b41c5d8..34f3eacb8f975 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -38,6 +38,7 @@ use std::any::Any; use std::collections::BTreeMap; use std::path::{Path, PathBuf}; use std::rc::Rc; +use std::sync::Arc; use owning_ref::ErasedBoxRef; use syntax::ast; use syntax::ext::base::SyntaxExtension; @@ -139,7 +140,7 @@ pub struct NativeLibrary { pub enum LoadedMacro { MacroDef(ast::Item), - ProcMacro(Rc), + ProcMacro(Arc), } #[derive(Copy, Clone, Debug)] @@ -251,7 +252,7 @@ pub struct ExternBodyNestedBodies { /// (it'd break incremental compilation) and should only be called pre-HIR (e.g. /// during resolve) pub trait CrateStore { - fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc; + fn crate_data_as_rc_any(&self, krate: CrateNum) -> Arc; // access to the metadata loader fn metadata_loader(&self) -> &MetadataLoader; @@ -260,7 +261,7 @@ pub trait CrateStore { fn def_key(&self, def: DefId) -> DefKey; fn def_path(&self, def: DefId) -> hir_map::DefPath; fn def_path_hash(&self, def: DefId) -> hir_map::DefPathHash; - fn def_path_table(&self, cnum: CrateNum) -> Rc; + fn def_path_table(&self, cnum: CrateNum) -> Arc; // "queries" used in resolve that aren't tracked for incremental compilation fn visibility_untracked(&self, def: DefId) -> ty::Visibility; @@ -323,7 +324,7 @@ pub struct DummyCrateStore; #[allow(unused_variables)] impl CrateStore for DummyCrateStore { - fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc + fn crate_data_as_rc_any(&self, krate: CrateNum) -> Arc { bug!("crate_data_as_rc_any") } // item info fn visibility_untracked(&self, def: DefId) -> ty::Visibility { bug!("visibility") } @@ -351,7 +352,7 @@ impl CrateStore for DummyCrateStore { fn def_path_hash(&self, def: DefId) -> hir_map::DefPathHash { bug!("def_path_hash") } - fn def_path_table(&self, cnum: CrateNum) -> Rc { + fn def_path_table(&self, cnum: CrateNum) -> Arc { bug!("def_path_table") } fn struct_field_names_untracked(&self, def: DefId) -> Vec { @@ -423,7 +424,7 @@ pub fn used_crates(tcx: TyCtxt, prefer: LinkagePreference) }) .collect::>(); let mut ordering = tcx.postorder_cnums(LOCAL_CRATE); - Rc::make_mut(&mut ordering).reverse(); + Arc::make_mut(&mut ordering).reverse(); libs.sort_by_key(|&(a, _)| { ordering.iter().position(|x| *x == a) }); diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 0383d5ca68232..a781a611e163e 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -27,7 +27,7 @@ use middle::region; use ty::{self, TyCtxt, adjustment}; use hir::{self, PatKind}; -use std::rc::Rc; +use std::sync::Arc; use syntax::ast; use syntax::ptr::P; use syntax_pos::Span; @@ -279,7 +279,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx, 'tcx> { param_env: ty::ParamEnv<'tcx>, region_scope_tree: &'a region::ScopeTree, tables: &'a ty::TypeckTables<'tcx>, - rvalue_promotable_map: Option>) + rvalue_promotable_map: Option>) -> Self { ExprUseVisitor { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 4071f81ea5143..8a1743bb5e8c1 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -85,6 +85,7 @@ use syntax::ast; use syntax_pos::Span; use std::fmt; +use std::sync::Arc; use std::rc::Rc; use util::nodemap::ItemLocalSet; @@ -286,7 +287,7 @@ pub struct MemCategorizationContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { pub tcx: TyCtxt<'a, 'gcx, 'tcx>, pub region_scope_tree: &'a region::ScopeTree, pub tables: &'a ty::TypeckTables<'tcx>, - rvalue_promotable_map: Option>, + rvalue_promotable_map: Option>, infcx: Option<&'a InferCtxt<'a, 'gcx, 'tcx>>, } @@ -395,7 +396,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx, 'tcx> { pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, region_scope_tree: &'a region::ScopeTree, tables: &'a ty::TypeckTables<'tcx>, - rvalue_promotable_map: Option>) + rvalue_promotable_map: Option>) -> MemCategorizationContext<'a, 'tcx, 'tcx> { MemCategorizationContext { tcx, diff --git a/src/librustc/middle/recursion_limit.rs b/src/librustc/middle/recursion_limit.rs index 6c87f750376fa..59e0e1d4925d4 100644 --- a/src/librustc/middle/recursion_limit.rs +++ b/src/librustc/middle/recursion_limit.rs @@ -18,7 +18,7 @@ use session::Session; use syntax::ast; -use std::cell::Cell; +use rustc_data_structures::lock::LockCell; pub fn update_limits(sess: &Session, krate: &ast::Crate) { update_limit(sess, krate, &sess.recursion_limit, "recursion_limit", @@ -27,7 +27,7 @@ pub fn update_limits(sess: &Session, krate: &ast::Crate) { "type length limit"); } -fn update_limit(sess: &Session, krate: &ast::Crate, limit: &Cell, +fn update_limit(sess: &Session, krate: &ast::Crate, limit: &LockCell, name: &str, description: &str) { for attr in &krate.attrs { if !attr.check_name(name) { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index a7882992d61c4..cb0a873e0a2db 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -20,7 +20,7 @@ use ty; use std::fmt; use std::mem; -use std::rc::Rc; +use std::sync::Arc; use syntax::codemap; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; @@ -1350,7 +1350,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> { } fn region_scope_tree<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Rc + -> Arc { let closure_base_def_id = tcx.closure_base_def_id(def_id); if closure_base_def_id != def_id { @@ -1392,7 +1392,7 @@ fn region_scope_tree<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) ScopeTree::default() }; - Rc::new(scope_tree) + Arc::new(scope_tree) } pub fn provide(providers: &mut Providers) { diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 18c26500dbe18..4da6a754aa838 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -30,10 +30,10 @@ use hir::{self, InlineAsm}; use std::ascii; use std::borrow::{Cow}; use std::cell::Ref; +use std::sync::Arc; use std::fmt::{self, Debug, Formatter, Write}; use std::{iter, u32}; use std::ops::{Index, IndexMut}; -use std::rc::Rc; use std::vec::IntoIter; use syntax::ast::{self, Name}; use syntax_pos::Span; @@ -1686,10 +1686,10 @@ pub struct UnsafetyViolation { #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct UnsafetyCheckResult { /// Violations that are propagated *upwards* from this function - pub violations: Rc<[UnsafetyViolation]>, + pub violations: Arc<[UnsafetyViolation]>, /// unsafe blocks in this function, along with whether they are used. This is /// used for the "unused_unsafe" lint. - pub unsafe_blocks: Rc<[(ast::NodeId, bool)]>, + pub unsafe_blocks: Arc<[(ast::NodeId, bool)]>, } /// The layout of generator state diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 3f53c89c9d6cb..0ed1b2eb651d8 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1010,6 +1010,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "prints the llvm optimization passes being run"), ast_json: bool = (false, parse_bool, [UNTRACKED], "print the AST as JSON and halt"), + query_threads: Option = (None, parse_opt_uint, [UNTRACKED], + "execute queries on a thread pool with N threads"), ast_json_noexpand: bool = (false, parse_bool, [UNTRACKED], "print the pre-expansion AST as JSON and halt"), ls: bool = (false, parse_bool, [UNTRACKED], @@ -1584,6 +1586,10 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) } } + if debugging_opts.query_threads == Some(0) { + early_error(error_format, "Value for codegen units must be a positive nonzero integer"); + } + if codegen_units == Some(0) { early_error(error_format, "Value for codegen units must be a positive nonzero integer"); } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 00a91eeb9c18e..a33b28a85ca89 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -23,6 +23,8 @@ use ty::tls; use util::nodemap::{FxHashMap, FxHashSet}; use util::common::{duration_to_secs_str, ErrorReported}; +use rustc_data_structures::lock::{RwLock, Lock, LockCell, ReadGuardRef}; + use syntax::ast::NodeId; use errors::{self, DiagnosticBuilder, DiagnosticId}; use errors::emitter::{Emitter, EmitterWriter}; @@ -39,13 +41,12 @@ use rustc_back::target::Target; use rustc_data_structures::flock; use jobserver::Client; -use std::cell::{self, Cell, RefCell}; use std::collections::HashMap; use std::env; +use std::sync::Arc; use std::fmt; use std::io::Write; use std::path::{Path, PathBuf}; -use std::rc::Rc; use std::sync::{Once, ONCE_INIT}; use std::time::Duration; @@ -62,10 +63,10 @@ pub struct Session { pub opts: config::Options, pub parse_sess: ParseSess, /// For a library crate, this is always none - pub entry_fn: RefCell>, - pub entry_type: Cell>, - pub plugin_registrar_fn: Cell>, - pub derive_registrar_fn: Cell>, + pub entry_fn: Lock>, + pub entry_type: LockCell>, + pub plugin_registrar_fn: LockCell>, + pub derive_registrar_fn: LockCell>, pub default_sysroot: Option, /// The name of the root source file of the crate, in the local file system. /// `None` means that there is no source file. @@ -73,88 +74,88 @@ pub struct Session { /// The directory the compiler has been executed in plus a flag indicating /// if the value stored here has been affected by path remapping. pub working_dir: (String, bool), - pub lint_store: RefCell, - pub buffered_lints: RefCell>, + pub lint_store: RwLock, + pub buffered_lints: Lock>, /// Set of (DiagnosticId, Option, message) tuples tracking /// (sub)diagnostics that have been set once, but should not be set again, /// in order to avoid redundantly verbose output (Issue #24690, #44953). - pub one_time_diagnostics: RefCell, String)>>, - pub plugin_llvm_passes: RefCell>, - pub plugin_attributes: RefCell>, - pub crate_types: RefCell>, - pub dependency_formats: RefCell, + pub one_time_diagnostics: Lock, String)>>, + pub plugin_llvm_passes: Lock>, + pub plugin_attributes: Lock>, + pub crate_types: RwLock>, + pub dependency_formats: Lock, /// The crate_disambiguator is constructed out of all the `-C metadata` /// arguments passed to the compiler. Its value together with the crate-name /// forms a unique global identifier for the crate. It is used to allow /// multiple crates with the same name to coexist. See the /// trans::back::symbol_names module for more information. - pub crate_disambiguator: RefCell>, - pub features: RefCell, + pub crate_disambiguator: Lock>, + pub features: RwLock, /// The maximum recursion limit for potentially infinitely recursive /// operations such as auto-dereference and monomorphization. - pub recursion_limit: Cell, + pub recursion_limit: LockCell, /// The maximum length of types during monomorphization. - pub type_length_limit: Cell, + pub type_length_limit: LockCell, /// The metadata::creader module may inject an allocator/panic_runtime /// dependency if it didn't already find one, and this tracks what was /// injected. - pub injected_allocator: Cell>, - pub allocator_kind: Cell>, - pub injected_panic_runtime: Cell>, + pub injected_allocator: LockCell>, + pub allocator_kind: LockCell>, + pub injected_panic_runtime: LockCell>, /// Map from imported macro spans (which consist of /// the localized span for the macro body) to the /// macro name and definition span in the source crate. - pub imported_macro_spans: RefCell>, + pub imported_macro_spans: Lock>, - incr_comp_session: RefCell, + incr_comp_session: RwLock, /// Some measurements that are being gathered during compilation. pub perf_stats: PerfStats, /// Data about code being compiled, gathered during compilation. - pub code_stats: RefCell, + pub code_stats: Lock, - next_node_id: Cell, + next_node_id: LockCell, /// If -zfuel=crate=n is specified, Some(crate). optimization_fuel_crate: Option, /// If -zfuel=crate=n is specified, initially set to n. Otherwise 0. - optimization_fuel_limit: Cell, + optimization_fuel_limit: LockCell, /// We're rejecting all further optimizations. - out_of_fuel: Cell, + out_of_fuel: LockCell, // The next two are public because the driver needs to read them. /// If -zprint-fuel=crate, Some(crate). pub print_fuel_crate: Option, /// Always set to zero and incremented so that we can print fuel expended by a crate. - pub print_fuel: Cell, + pub print_fuel: LockCell, /// Loaded up early on in the initialization of this `Session` to avoid /// false positives about a job server in our environment. pub jobserver_from_env: Option, /// Metadata about the allocators for the current crate being compiled - pub has_global_allocator: Cell, + pub has_global_allocator: LockCell, } pub struct PerfStats { /// The accumulated time needed for computing the SVH of the crate - pub svh_time: Cell, + pub svh_time: LockCell, /// The accumulated time spent on computing incr. comp. hashes - pub incr_comp_hashes_time: Cell, + pub incr_comp_hashes_time: LockCell, /// The number of incr. comp. hash computations performed - pub incr_comp_hashes_count: Cell, + pub incr_comp_hashes_count: LockCell, /// The number of bytes hashed when computing ICH values - pub incr_comp_bytes_hashed: Cell, + pub incr_comp_bytes_hashed: LockCell, /// The accumulated time spent on computing symbol hashes - pub symbol_hash_time: Cell, + pub symbol_hash_time: LockCell, /// The accumulated time spent decoding def path tables from metadata - pub decode_def_path_tables_time: Cell, + pub decode_def_path_tables_time: LockCell, } /// Enum to support dispatch of one-time diagnostics (in Session.diag_once) @@ -590,9 +591,9 @@ impl Session { }; } - pub fn incr_comp_session_dir(&self) -> cell::Ref { + pub fn incr_comp_session_dir(&self) -> ReadGuardRef { let incr_comp_session = self.incr_comp_session.borrow(); - cell::Ref::map(incr_comp_session, |incr_comp_session| { + ReadGuardRef::new(incr_comp_session).map(|incr_comp_session| { match *incr_comp_session { IncrCompSession::NotInitialized => { bug!("Trying to get session directory from IncrCompSession `{:?}`", @@ -607,7 +608,7 @@ impl Session { }) } - pub fn incr_comp_session_dir_opt(&self) -> Option> { + pub fn incr_comp_session_dir_opt(&self) -> Option> { if self.opts.incremental.is_some() { Some(self.incr_comp_session_dir()) } else { @@ -659,6 +660,12 @@ impl Session { ret } + /// Returns the number of query threads that should be used for this + /// compilation + pub fn query_threads(&self) -> usize { + self.opts.debugging_opts.query_threads.unwrap_or(1) + } + /// Returns the number of codegen units that should be used for this /// compilation pub fn codegen_units(&self) -> usize { @@ -706,14 +713,14 @@ pub fn build_session(sopts: config::Options, build_session_with_codemap(sopts, local_crate_source_file, registry, - Rc::new(codemap::CodeMap::new(file_path_mapping)), + Arc::new(codemap::CodeMap::new(file_path_mapping)), None) } pub fn build_session_with_codemap(sopts: config::Options, local_crate_source_file: Option, registry: errors::registry::Registry, - codemap: Rc, + codemap: Arc, emitter_dest: Option>) -> Session { // FIXME: This is not general enough to make the warning lint completely override @@ -731,7 +738,7 @@ pub fn build_session_with_codemap(sopts: config::Options, let treat_err_as_bug = sopts.debugging_opts.treat_err_as_bug; - let emitter: Box = match (sopts.error_format, emitter_dest) { + let emitter: Box = match (sopts.error_format, emitter_dest) { (config::ErrorOutputType::HumanReadable(color_config), None) => { Box::new(EmitterWriter::stderr(color_config, Some(codemap.clone()), false)) } @@ -766,7 +773,7 @@ pub fn build_session_with_codemap(sopts: config::Options, pub fn build_session_(sopts: config::Options, local_crate_source_file: Option, span_diagnostic: errors::Handler, - codemap: Rc) + codemap: Arc) -> Session { let host = match Target::search(config::host_triple()) { Ok(t) => t, @@ -789,10 +796,10 @@ pub fn build_session_(sopts: config::Options, }); let optimization_fuel_crate = sopts.debugging_opts.fuel.as_ref().map(|i| i.0.clone()); - let optimization_fuel_limit = Cell::new(sopts.debugging_opts.fuel.as_ref() + let optimization_fuel_limit = LockCell::new(sopts.debugging_opts.fuel.as_ref() .map(|i| i.1).unwrap_or(0)); let print_fuel_crate = sopts.debugging_opts.print_fuel.clone(); - let print_fuel = Cell::new(0); + let print_fuel = LockCell::new(0); let working_dir = match env::current_dir() { Ok(dir) => dir.to_string_lossy().into_owned(), @@ -802,50 +809,52 @@ pub fn build_session_(sopts: config::Options, }; let working_dir = file_path_mapping.map_prefix(working_dir); + //::rustc_data_structures::lock::assert_sync::(); + let sess = Session { target: target_cfg, host, opts: sopts, parse_sess: p_s, // For a library crate, this is always none - entry_fn: RefCell::new(None), - entry_type: Cell::new(None), - plugin_registrar_fn: Cell::new(None), - derive_registrar_fn: Cell::new(None), + entry_fn: Lock::new(None), + entry_type: LockCell::new(None), + plugin_registrar_fn: LockCell::new(None), + derive_registrar_fn: LockCell::new(None), default_sysroot, local_crate_source_file, working_dir, - lint_store: RefCell::new(lint::LintStore::new()), - buffered_lints: RefCell::new(Some(lint::LintBuffer::new())), - one_time_diagnostics: RefCell::new(FxHashSet()), - plugin_llvm_passes: RefCell::new(Vec::new()), - plugin_attributes: RefCell::new(Vec::new()), - crate_types: RefCell::new(Vec::new()), - dependency_formats: RefCell::new(FxHashMap()), - crate_disambiguator: RefCell::new(None), - features: RefCell::new(feature_gate::Features::new()), - recursion_limit: Cell::new(64), - type_length_limit: Cell::new(1048576), - next_node_id: Cell::new(NodeId::new(1)), - injected_allocator: Cell::new(None), - allocator_kind: Cell::new(None), - injected_panic_runtime: Cell::new(None), - imported_macro_spans: RefCell::new(HashMap::new()), - incr_comp_session: RefCell::new(IncrCompSession::NotInitialized), + lint_store: RwLock::new(lint::LintStore::new()), + buffered_lints: Lock::new(Some(lint::LintBuffer::new())), + one_time_diagnostics: Lock::new(FxHashSet()), + plugin_llvm_passes: Lock::new(Vec::new()), + plugin_attributes: Lock::new(Vec::new()), + crate_types: RwLock::new(Vec::new()), + dependency_formats: Lock::new(FxHashMap()), + crate_disambiguator: Lock::new(None), + features: RwLock::new(feature_gate::Features::new()), + recursion_limit: LockCell::new(64), + type_length_limit: LockCell::new(1048576), + next_node_id: LockCell::new(NodeId::new(1)), + injected_allocator: LockCell::new(None), + allocator_kind: LockCell::new(None), + injected_panic_runtime: LockCell::new(None), + imported_macro_spans: Lock::new(HashMap::new()), + incr_comp_session: RwLock::new(IncrCompSession::NotInitialized), perf_stats: PerfStats { - svh_time: Cell::new(Duration::from_secs(0)), - incr_comp_hashes_time: Cell::new(Duration::from_secs(0)), - incr_comp_hashes_count: Cell::new(0), - incr_comp_bytes_hashed: Cell::new(0), - symbol_hash_time: Cell::new(Duration::from_secs(0)), - decode_def_path_tables_time: Cell::new(Duration::from_secs(0)), + svh_time: LockCell::new(Duration::from_secs(0)), + incr_comp_hashes_time: LockCell::new(Duration::from_secs(0)), + incr_comp_hashes_count: LockCell::new(0), + incr_comp_bytes_hashed: LockCell::new(0), + symbol_hash_time: LockCell::new(Duration::from_secs(0)), + decode_def_path_tables_time: LockCell::new(Duration::from_secs(0)), }, - code_stats: RefCell::new(CodeStats::new()), + code_stats: Lock::new(CodeStats::new()), optimization_fuel_crate, optimization_fuel_limit, print_fuel_crate, print_fuel, - out_of_fuel: Cell::new(false), + out_of_fuel: LockCell::new(false), // Note that this is unsafe because it may misinterpret file descriptors // on Unix as jobserver file descriptors. We hopefully execute this near // the beginning of the process though to ensure we don't get false @@ -863,7 +872,7 @@ pub fn build_session_(sopts: config::Options, }); (*GLOBAL_JOBSERVER).clone() }, - has_global_allocator: Cell::new(false), + has_global_allocator: LockCell::new(false), }; sess @@ -916,7 +925,7 @@ pub enum IncrCompSession { } pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { - let emitter: Box = match output { + let emitter: Box = match output { config::ErrorOutputType::HumanReadable(color_config) => { Box::new(EmitterWriter::stderr(color_config, None, false)) } @@ -931,7 +940,7 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { } pub fn early_warn(output: config::ErrorOutputType, msg: &str) { - let emitter: Box = match output { + let emitter: Box = match output { config::ErrorOutputType::HumanReadable(color_config) => { Box::new(EmitterWriter::stderr(color_config, None, false)) } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index c08fe187f99bf..f02877b81ba8a 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -25,6 +25,7 @@ use ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable, ToPredicate}; use ty::error::{ExpectedFound, TypeError}; use infer::{InferCtxt}; +use std::sync::Arc; use std::rc::Rc; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; @@ -653,11 +654,11 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn vtable_methods<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) - -> Rc)>>> + -> Arc)>>> { debug!("vtable_methods({:?})", trait_ref); - Rc::new( + Arc::new( supertraits(tcx, trait_ref).flat_map(move |trait_ref| { let trait_methods = tcx.associated_items(trait_ref.def_id()) .filter(|item| item.kind == ty::AssociatedKind::Method); diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 7716770d318ba..220b80f4e95ca 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -40,10 +40,10 @@ use ty::fast_reject; use ty::relate::TypeRelation; use middle::lang_items; +use rustc_data_structures::lock::Lock; use rustc_data_structures::bitvec::BitVector; use rustc_data_structures::snapshot_vec::{SnapshotVecDelegate, SnapshotVec}; use std::iter; -use std::cell::RefCell; use std::cmp; use std::fmt; use std::marker::PhantomData; @@ -144,7 +144,7 @@ struct TraitObligationStack<'prev, 'tcx: 'prev> { #[derive(Clone)] pub struct SelectionCache<'tcx> { - hashmap: RefCell, + hashmap: Lock, WithDepNode>>>>, } @@ -409,7 +409,7 @@ impl EvaluationResult { #[derive(Clone)] pub struct EvaluationCache<'tcx> { - hashmap: RefCell, WithDepNode>> + hashmap: Lock, WithDepNode>> } impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { @@ -3284,7 +3284,7 @@ impl<'tcx> TraitObligation<'tcx> { impl<'tcx> SelectionCache<'tcx> { pub fn new() -> SelectionCache<'tcx> { SelectionCache { - hashmap: RefCell::new(FxHashMap()) + hashmap: Lock::new(FxHashMap()) } } } @@ -3292,7 +3292,7 @@ impl<'tcx> SelectionCache<'tcx> { impl<'tcx> EvaluationCache<'tcx> { pub fn new() -> EvaluationCache<'tcx> { EvaluationCache { - hashmap: RefCell::new(FxHashMap()) + hashmap: Lock::new(FxHashMap()) } } } diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index d8d0715ff3957..47ca246755321 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -28,7 +28,7 @@ use traits::{self, Reveal, ObligationCause}; use traits::select::IntercrateAmbiguityCause; use ty::{self, TyCtxt, TypeFoldable}; use syntax_pos::DUMMY_SP; -use std::rc::Rc; +use std::sync::Arc; pub mod specialization_graph; @@ -293,7 +293,7 @@ impl SpecializesCache { // Query provider for `specialization_graph_of`. pub(super) fn specialization_graph_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_id: DefId) - -> Rc { + -> Arc { let mut sg = specialization_graph::Graph::new(); let mut trait_impls = Vec::new(); @@ -356,7 +356,7 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx } } - Rc::new(sg) + Arc::new(sg) } /// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index da9dbc0e2c999..5ca0c85f893f8 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -17,7 +17,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, use traits; use ty::{self, TyCtxt, TypeFoldable}; use ty::fast_reject::{self, SimplifiedType}; -use std::rc::Rc; +use std::sync::Arc; use syntax::ast::Name; use util::nodemap::{DefIdMap, FxHashMap}; @@ -308,7 +308,7 @@ impl<'a, 'gcx, 'tcx> Node { pub struct Ancestors { trait_def_id: DefId, - specialization_graph: Rc, + specialization_graph: Arc, current_source: Option, } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 193c36736077e..3471354955ffb 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -54,16 +54,16 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap, use arena::{TypedArena, DroplessArena}; use rustc_const_math::{ConstInt, ConstUsize}; use rustc_data_structures::indexed_vec::IndexVec; +use rustc_data_structures::lock::Lock; use std::any::Any; use std::borrow::Borrow; -use std::cell::{Cell, RefCell}; +use std::cell::Cell; use std::cmp::Ordering; use std::collections::hash_map::{self, Entry}; use std::hash::{Hash, Hasher}; use std::mem; use std::ops::Deref; use std::iter; -use std::rc::Rc; use std::sync::mpsc; use std::sync::Arc; use syntax::abi; @@ -75,6 +75,20 @@ use syntax_pos::Span; use hir; +pub struct AllArenas<'tcx> { + pub global: GlobalArenas<'tcx>, + pub interner: DroplessArena, +} + +impl<'tcx> AllArenas<'tcx> { + pub fn new() -> Self { + AllArenas { + global: GlobalArenas::new(), + interner: DroplessArena::new(), + } + } +} + /// Internal storage pub struct GlobalArenas<'tcx> { // internings @@ -109,26 +123,26 @@ pub struct CtxtInterners<'tcx> { /// Specifically use a speedy hash algorithm for these hash sets, /// they're accessed quite often. - type_: RefCell>>>, - type_list: RefCell>>>>, - substs: RefCell>>>, - region: RefCell>>, - existential_predicates: RefCell>>>>, - predicates: RefCell>>>>, - const_: RefCell>>>, + type_: Lock>>>, + type_list: Lock>>>>, + substs: Lock>>>, + region: Lock>>, + existential_predicates: Lock>>>>, + predicates: Lock>>>>, + const_: Lock>>>, } impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { fn new(arena: &'tcx DroplessArena) -> CtxtInterners<'tcx> { CtxtInterners { - arena, - type_: RefCell::new(FxHashSet()), - type_list: RefCell::new(FxHashSet()), - substs: RefCell::new(FxHashSet()), - region: RefCell::new(FxHashSet()), - existential_predicates: RefCell::new(FxHashSet()), - predicates: RefCell::new(FxHashSet()), - const_: RefCell::new(FxHashSet()), + arena: arena, + type_: Lock::new(FxHashSet()), + type_list: Lock::new(FxHashSet()), + substs: Lock::new(FxHashSet()), + region: Lock::new(FxHashSet()), + existential_predicates: Lock::new(FxHashSet()), + predicates: Lock::new(FxHashSet()), + const_: Lock::new(FxHashSet()), } } @@ -386,9 +400,9 @@ pub struct TypeckTables<'tcx> { /// Set of trait imports actually used in the method resolution. /// This is used for warning unused imports. During type - /// checking, this `Rc` should not be cloned: it must have a ref-count + /// checking, this `Arc` should not be cloned: it must have a ref-count /// of 1 so that we can insert things into the set mutably. - pub used_trait_imports: Rc, + pub used_trait_imports: Arc, /// If any errors occurred while type-checking this body, /// this field will be set to `true`. @@ -418,7 +432,7 @@ impl<'tcx> TypeckTables<'tcx> { liberated_fn_sigs: ItemLocalMap(), fru_field_types: ItemLocalMap(), cast_kinds: ItemLocalMap(), - used_trait_imports: Rc::new(DefIdSet()), + used_trait_imports: Arc::new(DefIdSet()), tainted_by_errors: false, free_region_map: FreeRegionMap::new(), } @@ -833,12 +847,12 @@ impl<'tcx> CommonTypes<'tcx> { /// README](README.md) for more deatils. #[derive(Copy, Clone)] pub struct TyCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - gcx: &'a GlobalCtxt<'gcx>, + gcx: &'a ThreadCtxt<'gcx>, interners: &'a CtxtInterners<'tcx> } impl<'a, 'gcx, 'tcx> Deref for TyCtxt<'a, 'gcx, 'tcx> { - type Target = &'a GlobalCtxt<'gcx>; + type Target = &'a ThreadCtxt<'gcx>; fn deref(&self) -> &Self::Target { &self.gcx } @@ -865,11 +879,11 @@ pub struct GlobalCtxt<'tcx> { /// Map indicating what traits are in scope for places where this /// is relevant; generated by resolve. trait_map: FxHashMap>>>>, + Arc>>>>, /// Export map produced by name resolution. - export_map: FxHashMap>>, + export_map: FxHashMap>>, named_region_map: NamedRegionMap, @@ -884,14 +898,14 @@ pub struct GlobalCtxt<'tcx> { // Records the free variables refrenced by every closure // expression. Do not track deps for this, just recompute it from // scratch every time. - freevars: FxHashMap>>, + freevars: FxHashMap>>, maybe_unused_trait_imports: FxHashSet, maybe_unused_extern_crates: Vec<(DefId, Span)>, // Internal cache for metadata decoding. No need to track deps on this. - pub rcache: RefCell>>, + pub rcache: Lock>>, /// Caches the results of trait selection. This cache is used /// for things that do not have to do with the parameters in scope. @@ -909,22 +923,19 @@ pub struct GlobalCtxt<'tcx> { /// Data layout specification for the current target. pub data_layout: TargetDataLayout, - /// Used to prevent layout from recursing too deeply. - pub layout_depth: Cell, - /// Map from function to the `#[derive]` mode that it's defining. Only used /// by `proc-macro` crates. - pub derive_macros: RefCell>, + pub derive_macros: Lock>, - stability_interner: RefCell>, + stability_interner: Lock>, - layout_interner: RefCell>, + layout_interner: Lock>, /// A vector of every trait accessible in the whole crate /// (i.e. including those from subcrates). This is used only for /// error reporting, and so is lazily initialized and generally /// shouldn't taint the common path (hence the RefCell). - pub all_traits: RefCell>>, + pub all_traits: Lock>>, /// A general purpose channel to throw data out the back towards LLVM worker /// threads. @@ -932,12 +943,45 @@ pub struct GlobalCtxt<'tcx> { /// This is intended to only get used during the trans phase of the compiler /// when satisfying the query for a particular codegen unit. Internally in /// the query it'll send data along this channel to get processed later. - pub tx_to_llvm_workers: mpsc::Sender>, + pub tx_to_llvm_workers: Lock>>, output_filenames: Arc, } -impl<'tcx> GlobalCtxt<'tcx> { +fn _assert_gcx_sync<'tcx>() { + use ::rustc_data_structures::lock::assert_sync; + + assert_sync::<&'tcx GlobalArenas<'tcx>>(); + assert_sync::>(); + //assert_sync::<&'tcx CrateStore>(); + assert_sync::<&'tcx Session>(); + assert_sync::(); + assert_sync::>(); + assert_sync::>(); + assert_sync::>>>>>(); + assert_sync::>>>(); + assert_sync::(); + //assert_sync::>(); + //assert_sync::>(); + assert_sync::>>>(); + assert_sync::>(); + assert_sync::>(); + assert_sync::>>>(); + assert_sync::>(); + assert_sync::>(); + assert_sync::(); + assert_sync::(); + assert_sync::>>(); + assert_sync::>>(); + assert_sync::>>(); + assert_sync::>>>(); + assert_sync::>>>(); + assert_sync::>(); +} + +impl<'tcx> ThreadCtxt<'tcx> { /// Get the global TyCtxt. pub fn global_tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> { TyCtxt { @@ -947,6 +991,24 @@ impl<'tcx> GlobalCtxt<'tcx> { } } +/// A thread local context. +/// Each worker thread in a query thread pool has one of these. +pub struct ThreadCtxt<'tcx> { + /// The global context shared between threads + global: Arc>, + + /// Used to prevent layout from recursing too deeply. + pub layout_depth: Cell, +} + +impl<'tcx> Deref for ThreadCtxt<'tcx> { + type Target = GlobalCtxt<'tcx>; + + fn deref(&self) -> &Self::Target { + &*self.global + } +} + impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics { self.global_arenas.generics.alloc(generics) @@ -1052,8 +1114,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { cstore: &'tcx CrateStore, local_providers: ty::maps::Providers<'tcx>, extern_providers: ty::maps::Providers<'tcx>, - arenas: &'tcx GlobalArenas<'tcx>, - arena: &'tcx DroplessArena, + arenas: &'tcx AllArenas<'tcx>, resolutions: ty::Resolutions, named_region_map: resolve_lifetime::NamedRegionMap, hir: hir_map::Map<'tcx>, @@ -1065,7 +1126,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { where F: for<'b> FnOnce(TyCtxt<'b, 'tcx, 'tcx>) -> R { let data_layout = TargetDataLayout::parse(s); - let interners = CtxtInterners::new(arena); + let interners = CtxtInterners::new(&arenas.interner); let common_types = CommonTypes::new(&interners); let dep_graph = hir.dep_graph.clone(); let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0); @@ -1073,7 +1134,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { providers[LOCAL_CRATE] = local_providers; let def_path_hash_to_def_id = if s.opts.build_dep_graph() { - let upstream_def_path_tables: Vec<(CrateNum, Rc<_>)> = cstore + let upstream_def_path_tables: Vec<(CrateNum, Arc<_>)> = cstore .crates_untracked() .iter() .map(|&cnum| (cnum, cstore.def_path_table(cnum))) @@ -1108,37 +1169,39 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { for (k, v) in resolutions.trait_map { let hir_id = hir.node_to_hir_id(k); let map = trait_map.entry(hir_id.owner) - .or_insert_with(|| Rc::new(FxHashMap())); - Rc::get_mut(map).unwrap() + .or_insert_with(|| Arc::new(FxHashMap())); + Arc::get_mut(map).unwrap() .insert(hir_id.local_id, - Rc::new(StableVec::new(v))); + Arc::new(StableVec::new(v))); } let mut defs = FxHashMap(); for (k, v) in named_region_map.defs { let hir_id = hir.node_to_hir_id(k); let map = defs.entry(hir_id.owner) - .or_insert_with(|| Rc::new(FxHashMap())); - Rc::get_mut(map).unwrap().insert(hir_id.local_id, v); + .or_insert_with(|| Arc::new(FxHashMap())); + Arc::get_mut(map).unwrap().insert(hir_id.local_id, v); } let mut late_bound = FxHashMap(); for k in named_region_map.late_bound { let hir_id = hir.node_to_hir_id(k); let map = late_bound.entry(hir_id.owner) - .or_insert_with(|| Rc::new(FxHashSet())); - Rc::get_mut(map).unwrap().insert(hir_id.local_id); + .or_insert_with(|| Arc::new(FxHashSet())); + Arc::get_mut(map).unwrap().insert(hir_id.local_id); } let mut object_lifetime_defaults = FxHashMap(); for (k, v) in named_region_map.object_lifetime_defaults { let hir_id = hir.node_to_hir_id(k); let map = object_lifetime_defaults.entry(hir_id.owner) - .or_insert_with(|| Rc::new(FxHashMap())); - Rc::get_mut(map).unwrap().insert(hir_id.local_id, Rc::new(v)); + .or_insert_with(|| Arc::new(FxHashMap())); + Arc::get_mut(map).unwrap().insert(hir_id.local_id, Arc::new(v)); } - tls::enter_global(GlobalCtxt { + //::rustc_data_structures::lock::assert_sync::(); + + let gcx = GlobalCtxt { sess: s, cstore, - global_arenas: arenas, + global_arenas: &arenas.global, global_interners: interners, dep_graph: dep_graph.clone(), on_disk_query_result_cache, @@ -1150,10 +1213,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }, trait_map, export_map: resolutions.export_map.into_iter().map(|(k, v)| { - (k, Rc::new(v)) + (k, Arc::new(v)) }).collect(), freevars: resolutions.freevars.into_iter().map(|(k, v)| { - (hir.local_def_id(k), Rc::new(v)) + (hir.local_def_id(k), Arc::new(v)) }).collect(), maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports @@ -1168,19 +1231,25 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { hir, def_path_hash_to_def_id, maps: maps::Maps::new(providers), - rcache: RefCell::new(FxHashMap()), + rcache: Lock::new(FxHashMap()), selection_cache: traits::SelectionCache::new(), evaluation_cache: traits::EvaluationCache::new(), crate_name: Symbol::intern(crate_name), data_layout, - layout_interner: RefCell::new(FxHashSet()), - layout_depth: Cell::new(0), - derive_macros: RefCell::new(NodeMap()), - stability_interner: RefCell::new(FxHashSet()), - all_traits: RefCell::new(None), - tx_to_llvm_workers: tx, + layout_interner: Lock::new(FxHashSet()), + derive_macros: Lock::new(NodeMap()), + stability_interner: Lock::new(FxHashSet()), + all_traits: Lock::new(None), + tx_to_llvm_workers: Lock::new(tx), output_filenames: Arc::new(output_filenames.clone()), - }, f) + }; + + let thread_ctxt = ThreadCtxt { + global: Arc::new(gcx), + layout_depth: Cell::new(0), + }; + + tls::enter_global(thread_ctxt, f) } pub fn consider_optimizing String>(&self, msg: T) -> bool { @@ -1188,11 +1257,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.sess.consider_optimizing(&cname, msg) } - pub fn lang_items(self) -> Rc { + pub fn lang_items(self) -> Arc { self.get_lang_items(LOCAL_CRATE) } - pub fn stability(self) -> Rc> { + pub fn stability(self) -> Arc> { // FIXME(#42293) we should actually track this, but fails too many tests // today. self.dep_graph.with_ignore(|| { @@ -1200,7 +1269,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }) } - pub fn crates(self) -> Rc> { + pub fn crates(self) -> Arc> { self.all_crate_nums(LOCAL_CRATE) } @@ -1261,7 +1330,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Note that this is *untracked* and should only be used within the query // system if the result is otherwise tracked through queries - pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Rc { + pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Arc { self.cstore.crate_data_as_rc_any(cnum) } @@ -1321,7 +1390,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { } } -impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> { +impl<'gcx: 'tcx, 'tcx> ThreadCtxt<'gcx> { /// Call the closure with a local `TyCtxt` using the given arena. pub fn enter_local(&self, arena: &'tcx DroplessArena, f: F) -> R where F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R @@ -1474,7 +1543,7 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Slice> { } pub mod tls { - use super::{CtxtInterners, GlobalCtxt, TyCtxt}; + use super::{CtxtInterners, ThreadCtxt, TyCtxt}; use std::cell::Cell; use std::fmt; @@ -1483,11 +1552,11 @@ pub mod tls { /// Marker types used for the scoped TLS slot. /// The type context cannot be used directly because the scoped TLS /// in libstd doesn't allow types generic over lifetimes. - enum ThreadLocalGlobalCtxt {} + enum ThreadLocalThreadCtxt {} enum ThreadLocalInterners {} thread_local! { - static TLS_TCX: Cell> = Cell::new(None) } @@ -1497,7 +1566,7 @@ pub mod tls { }) } - pub fn enter_global<'gcx, F, R>(gcx: GlobalCtxt<'gcx>, f: F) -> R + pub fn enter_global<'gcx, F, R>(gcx: ThreadCtxt<'gcx>, f: F) -> R where F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'gcx>) -> R { syntax_pos::SPAN_DEBUG.with(|span_dbg| { @@ -1509,12 +1578,12 @@ pub mod tls { }) } - pub fn enter<'a, 'gcx: 'tcx, 'tcx, F, R>(gcx: &'a GlobalCtxt<'gcx>, + pub fn enter<'a, 'gcx: 'tcx, 'tcx, F, R>(gcx: &'a ThreadCtxt<'gcx>, interners: &'a CtxtInterners<'tcx>, f: F) -> R where F: FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R { - let gcx_ptr = gcx as *const _ as *const ThreadLocalGlobalCtxt; + let gcx_ptr = gcx as *const _ as *const ThreadLocalThreadCtxt; let interners_ptr = interners as *const _ as *const ThreadLocalInterners; TLS_TCX.with(|tls| { let prev = tls.get(); @@ -1533,7 +1602,7 @@ pub mod tls { { TLS_TCX.with(|tcx| { let (gcx, interners) = tcx.get().unwrap(); - let gcx = unsafe { &*(gcx as *const GlobalCtxt) }; + let gcx = unsafe { &*(gcx as *const ThreadCtxt) }; let interners = unsafe { &*(interners as *const CtxtInterners) }; f(TyCtxt { gcx, @@ -2183,7 +2252,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { lint::struct_lint_level(self.sess, lint, level, src, None, msg) } - pub fn in_scope_traits(self, id: HirId) -> Option>> { + pub fn in_scope_traits(self, id: HirId) -> Option>> { self.in_scope_traits_map(id.owner) .and_then(|map| map.get(&id.local_id).cloned()) } @@ -2200,7 +2269,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn object_lifetime_defaults(self, id: HirId) - -> Option>> + -> Option>> { self.object_lifetime_defaults_map(id.owner) .and_then(|map| map.get(&id.local_id).cloned()) @@ -2252,12 +2321,12 @@ impl InternIteratorElement for Result { } struct NamedRegionMap { - defs: FxHashMap>>, - late_bound: FxHashMap>>, + defs: FxHashMap>>, + late_bound: FxHashMap>>, object_lifetime_defaults: FxHashMap< DefIndex, - Rc>>>, + Arc>>>, >, } @@ -2286,7 +2355,7 @@ pub fn provide(providers: &mut ty::maps::Providers) { // Once red/green incremental compilation lands we should be able to // remove this because while the crate changes often the lint level map // will change rarely. - tcx.dep_graph.with_ignore(|| Rc::new(middle::lang_items::collect(tcx))) + tcx.dep_graph.with_ignore(|| Arc::new(middle::lang_items::collect(tcx))) }; providers.freevars = |tcx, id| tcx.gcx.freevars.get(&id).cloned(); providers.maybe_unused_trait_import = |tcx, id| { @@ -2294,12 +2363,12 @@ pub fn provide(providers: &mut ty::maps::Providers) { }; providers.maybe_unused_extern_crates = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Rc::new(tcx.maybe_unused_extern_crates.clone()) + Arc::new(tcx.maybe_unused_extern_crates.clone()) }; providers.stability_index = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Rc::new(stability::Index::new(tcx)) + Arc::new(stability::Index::new(tcx)) }; providers.lookup_stability = |tcx, id| { assert_eq!(id.krate, LOCAL_CRATE); @@ -2317,11 +2386,11 @@ pub fn provide(providers: &mut ty::maps::Providers) { }; providers.all_crate_nums = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Rc::new(tcx.cstore.crates_untracked()) + Arc::new(tcx.cstore.crates_untracked()) }; providers.postorder_cnums = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Rc::new(tcx.cstore.postorder_cnums_untracked()) + Arc::new(tcx.cstore.postorder_cnums_untracked()) }; providers.output_filenames = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 320f651484987..45a1603f8e8f0 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -47,7 +47,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::StableVec; use std::ops::Deref; -use std::rc::Rc; use std::sync::Arc; use syntax_pos::{Span, DUMMY_SP}; use syntax_pos::symbol::InternedString; @@ -118,17 +117,17 @@ define_maps! { <'tcx> /// Get a map with the variance of every item; use `item_variance` /// instead. - [] fn crate_variances: crate_variances(CrateNum) -> Rc, + [] fn crate_variances: crate_variances(CrateNum) -> Arc, /// Maps from def-id of a type or region parameter to its /// (inferred) variance. - [] fn variances_of: ItemVariances(DefId) -> Rc>, + [] fn variances_of: ItemVariances(DefId) -> Arc>, /// Maps from def-id of a type to its (inferred) outlives. [] fn inferred_outlives_of: InferredOutlivesOf(DefId) -> Vec>, /// Maps from an impl/trait def-id to a list of the def-ids of its items - [] fn associated_item_def_ids: AssociatedItemDefIds(DefId) -> Rc>, + [] fn associated_item_def_ids: AssociatedItemDefIds(DefId) -> Arc>, /// Maps from a trait item to the trait item "descriptor" [] fn associated_item: AssociatedItems(DefId) -> ty::AssociatedItem, @@ -139,17 +138,17 @@ define_maps! { <'tcx> /// Maps a DefId of a type to a list of its inherent impls. /// Contains implementations of methods that are inherent to a type. /// Methods in these implementations don't need to be exported. - [] fn inherent_impls: InherentImpls(DefId) -> Rc>, + [] fn inherent_impls: InherentImpls(DefId) -> Arc>, /// Set of all the def-ids in this crate that have MIR associated with /// them. This includes all the body owners, but also things like struct /// constructors. - [] fn mir_keys: mir_keys(CrateNum) -> Rc, + [] fn mir_keys: mir_keys(CrateNum) -> Arc, /// Maps DefId's that have an associated Mir to the result /// of the MIR qualify_consts pass. The actual meaning of /// the value isn't known except to the pass itself. - [] fn mir_const_qualif: MirConstQualif(DefId) -> (u8, Rc>), + [] fn mir_const_qualif: MirConstQualif(DefId) -> (u8, Arc>), /// Fetch the MIR for a given def-id right after it's built - this includes /// unreachable code. @@ -189,13 +188,13 @@ define_maps! { <'tcx> [] fn typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>, - [] fn used_trait_imports: UsedTraitImports(DefId) -> Rc, + [] fn used_trait_imports: UsedTraitImports(DefId) -> Arc, [] fn has_typeck_tables: HasTypeckTables(DefId) -> bool, [] fn coherent_trait: coherent_trait_dep_node((CrateNum, DefId)) -> (), - [] fn borrowck: BorrowCheck(DefId) -> Rc, + [] fn borrowck: BorrowCheck(DefId) -> Arc, // FIXME: shouldn't this return a `Result<(), BorrowckErrors>` instead? [] fn mir_borrowck: MirBorrowCheck(DefId) -> (), @@ -215,13 +214,13 @@ define_maps! { <'tcx> -> const_val::EvalResult<'tcx>, /// Performs the privacy check and computes "access levels". - [] fn privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Rc, + [] fn privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Arc, [] fn reachable_set: reachability_dep_node(CrateNum) -> ReachableSet, /// Per-body `region::ScopeTree`. The `DefId` should be the owner-def-id for the body; /// in the case of closures, this will be redirected to the enclosing function. - [] fn region_scope_tree: RegionScopeTree(DefId) -> Rc, + [] fn region_scope_tree: RegionScopeTree(DefId) -> Arc, [] fn mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx mir::Mir<'tcx>, @@ -232,22 +231,22 @@ define_maps! { <'tcx> [] fn def_span: DefSpan(DefId) -> Span, [] fn lookup_stability: LookupStability(DefId) -> Option<&'tcx attr::Stability>, [] fn lookup_deprecation_entry: LookupDeprecationEntry(DefId) -> Option, - [] fn item_attrs: ItemAttrs(DefId) -> Rc<[ast::Attribute]>, + [] fn item_attrs: ItemAttrs(DefId) -> Arc<[ast::Attribute]>, [] fn fn_arg_names: FnArgNames(DefId) -> Vec, [] fn impl_parent: ImplParent(DefId) -> Option, [] fn trait_of_item: TraitOfItem(DefId) -> Option, [] fn is_exported_symbol: IsExportedSymbol(DefId) -> bool, [] fn item_body_nested_bodies: ItemBodyNestedBodies(DefId) -> ExternBodyNestedBodies, [] fn const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool, - [] fn rvalue_promotable_map: RvaluePromotableMap(DefId) -> Rc, + [] fn rvalue_promotable_map: RvaluePromotableMap(DefId) -> Arc, [] fn is_mir_available: IsMirAvailable(DefId) -> bool, [] fn vtable_methods: vtable_methods_node(ty::PolyTraitRef<'tcx>) - -> Rc)>>>, + -> Arc)>>>, [] fn trans_fulfill_obligation: fulfill_obligation_dep_node( (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> Vtable<'tcx, ()>, - [] fn trait_impls_of: TraitImpls(DefId) -> Rc, - [] fn specialization_graph_of: SpecializationGraph(DefId) -> Rc, + [] fn trait_impls_of: TraitImpls(DefId) -> Arc, + [] fn specialization_graph_of: SpecializationGraph(DefId) -> Arc, [] fn is_object_safe: ObjectSafety(DefId) -> bool, // Get the ParameterEnvironment for a given item; this environment @@ -268,7 +267,7 @@ define_maps! { <'tcx> -> Result<&'tcx Layout, LayoutError<'tcx>>, [] fn dylib_dependency_formats: DylibDepFormats(CrateNum) - -> Rc>, + -> Arc>, [] fn is_panic_runtime: IsPanicRuntime(CrateNum) -> bool, [] fn is_compiler_builtins: IsCompilerBuiltins(CrateNum) -> bool, @@ -278,17 +277,17 @@ define_maps! { <'tcx> [] fn panic_strategy: GetPanicStrategy(CrateNum) -> PanicStrategy, [] fn is_no_builtins: IsNoBuiltins(CrateNum) -> bool, - [] fn extern_crate: ExternCrate(DefId) -> Rc>, + [] fn extern_crate: ExternCrate(DefId) -> Arc>, [] fn specializes: specializes_node((DefId, DefId)) -> bool, [] fn in_scope_traits_map: InScopeTraits(DefIndex) - -> Option>>>>, - [] fn module_exports: ModuleExports(DefId) -> Option>>, - [] fn lint_levels: lint_levels_node(CrateNum) -> Rc, + -> Option>>>>, + [] fn module_exports: ModuleExports(DefId) -> Option>>, + [] fn lint_levels: lint_levels_node(CrateNum) -> Arc, [] fn impl_defaultness: ImplDefaultness(DefId) -> hir::Defaultness, - [] fn exported_symbol_ids: ExportedSymbolIds(CrateNum) -> Rc, - [] fn native_libraries: NativeLibraries(CrateNum) -> Rc>, + [] fn exported_symbol_ids: ExportedSymbolIds(CrateNum) -> Arc, + [] fn native_libraries: NativeLibraries(CrateNum) -> Arc>, [] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option, [] fn derive_registrar_fn: DeriveRegistrarFn(CrateNum) -> Option, [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator, @@ -296,46 +295,46 @@ define_maps! { <'tcx> [] fn original_crate_name: OriginalCrateName(CrateNum) -> Symbol, [] fn implementations_of_trait: implementations_of_trait_node((CrateNum, DefId)) - -> Rc>, + -> Arc>, [] fn all_trait_implementations: AllTraitImplementations(CrateNum) - -> Rc>, + -> Arc>, [] fn is_dllimport_foreign_item: IsDllimportForeignItem(DefId) -> bool, [] fn is_statically_included_foreign_item: IsStaticallyIncludedForeignItem(DefId) -> bool, [] fn native_library_kind: NativeLibraryKind(DefId) -> Option, - [] fn link_args: link_args_node(CrateNum) -> Rc>, + [] fn link_args: link_args_node(CrateNum) -> Arc>, [] fn named_region_map: NamedRegion(DefIndex) -> - Option>>, + Option>>, [] fn is_late_bound_map: IsLateBound(DefIndex) -> - Option>>, + Option>>, [] fn object_lifetime_defaults_map: ObjectLifetimeDefaults(DefIndex) - -> Option>>>>, + -> Option>>>>, [] fn visibility: Visibility(DefId) -> ty::Visibility, [] fn dep_kind: DepKind(CrateNum) -> DepKind, [] fn crate_name: CrateName(CrateNum) -> Symbol, - [] fn item_children: ItemChildren(DefId) -> Rc>, + [] fn item_children: ItemChildren(DefId) -> Arc>, [] fn extern_mod_stmt_cnum: ExternModStmtCnum(DefId) -> Option, - [] fn get_lang_items: get_lang_items_node(CrateNum) -> Rc, - [] fn defined_lang_items: DefinedLangItems(CrateNum) -> Rc>, - [] fn missing_lang_items: MissingLangItems(CrateNum) -> Rc>, + [] fn get_lang_items: get_lang_items_node(CrateNum) -> Arc, + [] fn defined_lang_items: DefinedLangItems(CrateNum) -> Arc>, + [] fn missing_lang_items: MissingLangItems(CrateNum) -> Arc>, [] fn extern_const_body: ExternConstBody(DefId) -> ExternConstBody<'tcx>, [] fn visible_parent_map: visible_parent_map_node(CrateNum) - -> Rc>, + -> Arc>, [] fn missing_extern_crate_item: MissingExternCrateItem(CrateNum) -> bool, - [] fn used_crate_source: UsedCrateSource(CrateNum) -> Rc, - [] fn postorder_cnums: postorder_cnums_node(CrateNum) -> Rc>, + [] fn used_crate_source: UsedCrateSource(CrateNum) -> Arc, + [] fn postorder_cnums: postorder_cnums_node(CrateNum) -> Arc>, - [] fn freevars: Freevars(DefId) -> Option>>, + [] fn freevars: Freevars(DefId) -> Option>>, [] fn maybe_unused_trait_import: MaybeUnusedTraitImport(DefId) -> bool, [] fn maybe_unused_extern_crates: maybe_unused_extern_crates_node(CrateNum) - -> Rc>, + -> Arc>, - [] fn stability_index: stability_index_node(CrateNum) -> Rc>, - [] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Rc>, + [] fn stability_index: stability_index_node(CrateNum) -> Arc>, + [] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Arc>, [] fn exported_symbols: ExportedSymbols(CrateNum) -> Arc, SymbolExportLevel)>>, diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index 24ce8fb299598..cf86d9503c810 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -16,11 +16,12 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque, SpecializedDecoder}; use session::Session; use std::borrow::Cow; -use std::cell::RefCell; use std::collections::BTreeMap; use std::mem; use syntax::codemap::{CodeMap, StableFilemapId}; use syntax_pos::{BytePos, Span, NO_EXPANSION, DUMMY_SP}; +use rustc_data_structures::lock::Lock; +//use util::common::assert_sync; /// `OnDiskCache` provides an interface to incr. comp. data cached from the /// previous compilation session. This data will eventually include the results @@ -32,7 +33,7 @@ pub struct OnDiskCache<'sess> { // This field collects all Diagnostics emitted during the current // compilation session. - current_diagnostics: RefCell>>, + current_diagnostics: Lock>>, // This will eventually be needed for creating Decoders that can rebase // spans. @@ -78,16 +79,17 @@ impl<'sess> OnDiskCache<'sess> { prev_diagnostics, _prev_filemap_starts: header.prev_filemap_starts, codemap: sess.codemap(), - current_diagnostics: RefCell::new(FxHashMap()), + current_diagnostics: Lock::new(FxHashMap()), } } pub fn new_empty(codemap: &'sess CodeMap) -> OnDiskCache<'sess> { + //assert_sync::(); OnDiskCache { prev_diagnostics: FxHashMap(), _prev_filemap_starts: BTreeMap::new(), codemap, - current_diagnostics: RefCell::new(FxHashMap()), + current_diagnostics: Lock::new(FxHashMap()), } } diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index f5e1f384d60ea..b23ac79a92f1b 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -20,7 +20,6 @@ use ty::maps::config::QueryDescription; use ty::item_path; use rustc_data_structures::fx::{FxHashMap}; -use std::cell::RefMut; use std::marker::PhantomData; use std::mem; use syntax_pos::Span; @@ -55,9 +54,9 @@ impl QueryMap { } } -pub(super) struct CycleError<'a, 'tcx: 'a> { +pub(super) struct CycleError<'tcx> { span: Span, - cycle: RefMut<'a, [(Span, Query<'tcx>)]>, + cycle: Vec<(Span, Query<'tcx>)>, } impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { @@ -97,7 +96,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub(super) fn cycle_check(self, span: Span, query: Query<'gcx>, compute: F) - -> Result> + -> Result> where F: FnOnce() -> R { { @@ -106,7 +105,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { .find(|&(_, &(_, ref q))| *q == query) { return Err(CycleError { span, - cycle: RefMut::map(stack, |stack| &mut stack[i..]) + cycle: stack[i..].iter().cloned().collect(), }); } stack.push((span, query)); @@ -183,7 +182,7 @@ macro_rules! define_maps { [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*) => { use dep_graph::DepNodeIndex; - use std::cell::RefCell; + use rustc_data_structures::lock::Lock; define_map_struct! { tcx: $tcx, @@ -195,8 +194,8 @@ macro_rules! define_maps { -> Self { Maps { providers, - query_stack: RefCell::new(vec![]), - $($name: RefCell::new(QueryMap::new())),* + query_stack: Lock::new(vec![]), + $($name: Lock::new(QueryMap::new())),* } } } @@ -254,7 +253,7 @@ macro_rules! define_maps { fn try_get_with(tcx: TyCtxt<'a, $tcx, 'lcx>, mut span: Span, key: $K) - -> Result<$V, CycleError<'a, $tcx>> + -> Result<$V, CycleError<$tcx>> { debug!("ty::queries::{}::try_get_with(key={:?}, span={:?})", stringify!($name), @@ -375,7 +374,7 @@ macro_rules! define_maps { span: Span, dep_node_index: DepNodeIndex, dep_node: &DepNode) - -> Result<$V, CycleError<'a, $tcx>> + -> Result<$V, CycleError<$tcx>> { debug_assert!(tcx.dep_graph.is_green(dep_node_index)); @@ -437,7 +436,7 @@ macro_rules! define_maps { key: $K, span: Span, dep_node: DepNode) - -> Result<($V, DepNodeIndex), CycleError<'a, $tcx>> { + -> Result<($V, DepNodeIndex), CycleError<$tcx>> { debug_assert!(tcx.dep_graph.node_color(&dep_node).is_none()); profq_msg!(tcx, ProfileQueriesMsg::ProviderBegin); @@ -546,8 +545,8 @@ macro_rules! define_map_struct { input: ($(([$(modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => { pub struct Maps<$tcx> { providers: IndexVec>, - query_stack: RefCell)>>, - $($(#[$attr])* $name: RefCell>>,)* + query_stack: Lock)>>, + $($(#[$attr])* $name: Lock>>,)* } }; } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 0deababd21829..eed66e9208a4e 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -42,7 +42,7 @@ use std::fmt; use std::hash::{Hash, Hasher}; use std::iter::FromIterator; use std::ops::Deref; -use std::rc::Rc; +use std::sync::Arc; use std::slice; use std::vec::IntoIter; use std::mem; @@ -77,7 +77,7 @@ pub use self::sty::TypeVariants::*; pub use self::binding::BindingMode; pub use self::binding::BindingMode::*; -pub use self::context::{TyCtxt, GlobalArenas, tls, keep_local}; +pub use self::context::{TyCtxt, GlobalArenas, AllArenas, tls, keep_local}; pub use self::context::{Lift, TypeckTables}; pub use self::instance::{Instance, InstanceDef}; @@ -123,7 +123,7 @@ mod sty; /// *on-demand* infrastructure. #[derive(Clone)] pub struct CrateAnalysis { - pub access_levels: Rc, + pub access_levels: Arc, pub name: String, pub glob_map: Option, } @@ -317,10 +317,10 @@ pub struct CrateVariancesMap { /// For each item with generics, maps to a vector of the variance /// of its generics. If an item has no generics, it will have no /// entry. - pub variances: FxHashMap>>, + pub variances: FxHashMap>>, /// An empty vector, useful for cloning. - pub empty_variance: Rc>, + pub empty_variance: Arc>, } impl Variance { @@ -2018,7 +2018,7 @@ impl BorrowKind { #[derive(Debug, Clone)] pub enum Attributes<'gcx> { - Owned(Rc<[ast::Attribute]>), + Owned(Arc<[ast::Attribute]>), Borrowed(&'gcx [ast::Attribute]) } @@ -2505,7 +2505,7 @@ fn adt_dtorck_constraint<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Rc> { + -> Arc> { let id = tcx.hir.as_local_node_id(def_id).unwrap(); let item = tcx.hir.expect_item(id); let vec: Vec<_> = match item.node { @@ -2523,7 +2523,7 @@ fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait") }; - Rc::new(vec) + Arc::new(vec) } fn def_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Span { @@ -2623,7 +2623,7 @@ pub fn provide_extern(providers: &mut ty::maps::Providers) { /// (constructing this map requires touching the entire crate). #[derive(Clone, Debug)] pub struct CrateInherentImpls { - pub inherent_impls: DefIdMap>>, + pub inherent_impls: DefIdMap>>, } /// A set of constraints that need to be satisfied in order for diff --git a/src/librustc/ty/steal.rs b/src/librustc/ty/steal.rs index 0b0818888812f..dbc5d2ba358e0 100644 --- a/src/librustc/ty/steal.rs +++ b/src/librustc/ty/steal.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::cell::{Ref, RefCell}; +use rustc_data_structures::lock::{RwLock, ReadGuardRef}; use std::mem; /// The `Steal` struct is intended to used as the value for a query. @@ -32,18 +32,18 @@ use std::mem; /// /// FIXME(#41710) -- what is the best way to model linear queries? pub struct Steal { - value: RefCell> + value: RwLock> } impl Steal { pub fn new(value: T) -> Self { Steal { - value: RefCell::new(Some(value)) + value: RwLock::new(Some(value)) } } - pub fn borrow(&self) -> Ref { - Ref::map(self.value.borrow(), |opt| match *opt { + pub fn borrow(&self) -> ReadGuardRef, T> { + ReadGuardRef::new(self.value.borrow()).map(|opt| match *opt { None => bug!("attempted to read from stolen value"), Some(ref v) => v }) diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 0fbf9f1bd587b..4aa123ee73441 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -20,7 +20,7 @@ use ty::{Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; -use std::rc::Rc; +use std::sync::Arc; /// A trait's definition with type information. pub struct TraitDef { @@ -142,7 +142,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Query provider for `trait_impls_of`. pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_id: DefId) - -> Rc { + -> Arc { let mut remote_impls = Vec::new(); // Traits defined in the current crate can't have impls in upstream @@ -180,7 +180,7 @@ pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } - Rc::new(TraitImpls { + Arc::new(TraitImpls { blanket_impls: blanket_impls, non_blanket_impls: non_blanket_impls, }) diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 9e566d2b9071f..7534578cf6fb4 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -10,6 +10,8 @@ #![allow(non_camel_case_types)] +use rustc_data_structures::lock::LockCell; + use std::cell::{RefCell, Cell}; use std::collections::HashMap; use std::ffi::CString; @@ -24,6 +26,8 @@ use syntax_pos::{SpanData}; use ty::maps::{QueryMsg}; use dep_graph::{DepNode}; +pub fn assert_sync() {} + // The name of the associated type for `Fn` return types pub const FN_OUTPUT_NAME: &'static str = "Output"; @@ -205,7 +209,7 @@ pub fn to_readable_str(mut val: usize) -> String { groups.join("_") } -pub fn record_time(accu: &Cell, f: F) -> T where +pub fn record_time(accu: &LockCell, f: F) -> T where F: FnOnce() -> T, { let start = Instant::now(); diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 6be07878487b9..e153c161eba77 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -44,6 +44,7 @@ use rustc::util::nodemap::FxHashSet; use std::cell::RefCell; use std::fmt; use std::rc::Rc; +use std::sync::Arc; use std::hash::{Hash, Hasher}; use syntax::ast; use syntax_pos::{MultiSpan, Span}; @@ -86,7 +87,7 @@ pub struct AnalysisData<'a, 'tcx: 'a> { } fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) - -> Rc + -> Arc { debug!("borrowck(body_owner_def_id={:?})", owner_def_id); @@ -99,7 +100,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) // those things (notably the synthesized constructors from // tuple structs/variants) do not have an associated body // and do not need borrowchecking. - return Rc::new(BorrowCheckResult { + return Arc::new(BorrowCheckResult { used_mut_nodes: FxHashSet(), }) } @@ -127,7 +128,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) // Note that `mir_validated` is a "stealable" result; the // thief, `optimized_mir()`, forces borrowck, so we know that // is not yet stolen. - tcx.mir_validated(owner_def_id).borrow(); + let _guard = tcx.mir_validated(owner_def_id).borrow(); // option dance because you can't capture an uninitialized variable // by mut-ref. @@ -145,7 +146,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) } unused::check(&mut bccx, body); - Rc::new(BorrowCheckResult { + Arc::new(BorrowCheckResult { used_mut_nodes: bccx.used_mut_nodes.into_inner(), }) } @@ -243,7 +244,7 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> { // Some in `borrowck_fn` and cleared later tables: &'a ty::TypeckTables<'tcx>, - region_scope_tree: Rc, + region_scope_tree: Arc, owner_def_id: DefId, diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 343b1ed68b804..e149d053b80e2 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -11,3 +11,8 @@ crate-type = ["dylib"] [dependencies] log = "0.3" serialize = { path = "../libserialize" } +owning_ref = "0.3" + +[dependencies.parking_lot] +version = "0.5" +features = ["nightly", "owning_ref"] \ No newline at end of file diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index a733e9de5a1ab..6fd077e248856 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -327,7 +327,7 @@ macro_rules! newtype_index { #[derive(Clone, PartialEq, Eq)] pub struct IndexVec { pub raw: Vec, - _marker: PhantomData + _marker: PhantomData } impl serialize::Encodable for IndexVec { diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 3a20343033c23..088778af39a37 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -41,6 +41,8 @@ extern crate log; extern crate serialize as rustc_serialize; // used by deriving #[cfg(unix)] extern crate libc; +extern crate parking_lot; +extern crate owning_ref; pub use rustc_serialize::hex::ToHex; @@ -66,6 +68,7 @@ pub mod tuple_slice; pub mod veccell; pub mod control_flow_graph; pub mod flock; +pub mod lock; // See comments in src/librustc/lib.rs #[doc(hidden)] diff --git a/src/librustc_data_structures/lock.rs b/src/librustc_data_structures/lock.rs new file mode 100644 index 0000000000000..89fc1799e2720 --- /dev/null +++ b/src/librustc_data_structures/lock.rs @@ -0,0 +1,195 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::cmp::Ordering; + +use parking_lot; +use owning_ref::OwningRef; + +pub use std::sync::Arc as Rcd; + +pub type ReadGuardRef<'a, T, U = T> = OwningRef, U>; + +pub use parking_lot::RwLockReadGuard as ReadGuard; + +pub fn assert_sync() {} + +#[derive(Debug)] +pub struct RwLock(parking_lot::RwLock); + +const ERROR_CHECKING: bool = true; + +impl RwLock { + #[inline(always)] + pub fn new(inner: T) -> Self { + RwLock(parking_lot::RwLock::new(inner)) + } + + #[inline(always)] + pub fn borrow(&self) -> parking_lot::RwLockReadGuard { + if ERROR_CHECKING { + self.0.try_read().expect("lock was already held") + } else { + self.0.read() + } + } + + #[inline(always)] + pub fn borrow_mut(&self) -> parking_lot::RwLockWriteGuard { + if ERROR_CHECKING { + self.0.try_write().expect("lock was already held") + } else { + self.0.write() + } + } +} + +#[derive(Debug)] +pub struct LockCell(Lock); + +impl LockCell { + #[inline(always)] + pub fn new(inner: T) -> Self { + LockCell(Lock::new(inner)) + } + + #[inline(always)] + pub fn set(&self, new_inner: T) { + *self.0.lock() = new_inner; + } + + #[inline(always)] + pub fn get(&self) -> T where T: Copy { + *self.0.lock() + } + + #[inline(always)] + pub fn set_mut(&mut self, new_inner: T) { + *self.0.get_mut() = new_inner; + } + + #[inline(always)] + pub fn get_mut(&mut self) -> T where T: Copy { + *self.0.get_mut() + } + + #[inline(always)] + pub fn get_raw(&self) -> T where T: Copy { + *self.0.lock() + } +} + +impl LockCell> { + #[inline(always)] + pub fn take(&self) -> Option { + self.0.lock().take() + } +} + +impl Default for LockCell { + /// Creates a `LockCell`, with the `Default` value for T. + #[inline] + fn default() -> LockCell { + LockCell::new(Default::default()) + } +} + +impl PartialEq for LockCell { + #[inline] + fn eq(&self, other: &LockCell) -> bool { + self.get() == other.get() + } +} + +impl Eq for LockCell {} + +impl PartialOrd for LockCell { + #[inline] + fn partial_cmp(&self, other: &LockCell) -> Option { + self.get().partial_cmp(&other.get()) + } + + #[inline] + fn lt(&self, other: &LockCell) -> bool { + self.get() < other.get() + } + + #[inline] + fn le(&self, other: &LockCell) -> bool { + self.get() <= other.get() + } + + #[inline] + fn gt(&self, other: &LockCell) -> bool { + self.get() > other.get() + } + + #[inline] + fn ge(&self, other: &LockCell) -> bool { + self.get() >= other.get() + } +} + +impl Ord for LockCell { + #[inline] + fn cmp(&self, other: &LockCell) -> Ordering { + self.get().cmp(&other.get()) + } +} + +pub use parking_lot::MutexGuard as LockCellGuard; + +#[derive(Debug)] +pub struct Lock(parking_lot::Mutex); + +pub use parking_lot::MutexGuard as LockGuard; + +impl Lock { + #[inline(always)] + pub fn new(inner: T) -> Self { + Lock(parking_lot::Mutex::new(inner)) + } + + #[inline(always)] + pub fn into_inner(self) -> T { + self.0.into_inner() + } + + #[inline(always)] + pub fn get_mut(&mut self) -> &mut T { + self.0.get_mut() + } + + #[inline(always)] + pub fn lock(&self) -> parking_lot::MutexGuard { + if ERROR_CHECKING { + self.0.try_lock().expect("lock was already held") + } else { + self.0.lock() + } + } + + #[inline(always)] + pub fn borrow(&self) -> parking_lot::MutexGuard { + self.lock() + } + + #[inline(always)] + pub fn borrow_mut(&self) -> parking_lot::MutexGuard { + self.lock() + } +} + +impl Clone for Lock { + #[inline] + fn clone(&self) -> Self { + Lock::new(self.borrow().clone()) + } +} \ No newline at end of file diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs index 933e08811ce5d..1c5a95be4206a 100644 --- a/src/librustc_data_structures/transitive_relation.rs +++ b/src/librustc_data_structures/transitive_relation.rs @@ -10,16 +10,16 @@ use bitvec::BitMatrix; use fx::FxHashMap; +use lock::LockCell; use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; use stable_hasher::{HashStable, StableHasher, StableHasherResult}; -use std::cell::RefCell; use std::fmt::Debug; use std::hash::Hash; use std::mem; -#[derive(Clone, Debug)] -pub struct TransitiveRelation { +#[derive(Debug)] +pub struct TransitiveRelation { // List of elements. This is used to map from a T to a usize. elements: Vec, @@ -32,14 +32,33 @@ pub struct TransitiveRelation { // This is a cached transitive closure derived from the edges. // Currently, we build it lazilly and just throw out any existing - // copy whenever a new edge is added. (The RefCell is to permit + // copy whenever a new edge is added. (The LockCell is to permit // the lazy computation.) This is kind of silly, except for the // fact its size is tied to `self.elements.len()`, so I wanted to // wait before building it up to avoid reallocating as new edges // are added with new elements. Perhaps better would be to ask the // user for a batch of edges to minimize this effect, but I // already wrote the code this way. :P -nmatsakis - closure: RefCell>, + closure: LockCell>, +} + +impl Clone for TransitiveRelation { + fn clone(&self) -> Self { + TransitiveRelation { + elements: self.elements.clone(), + map: self.map.clone(), + edges: self.edges.clone(), + closure: { + // Borrow the closure for the duration of the clone. + // This could cause the closure to be recomputed if there's + // an operation which require the closure during the clone + let closure = self.closure.take(); + let new_closure = closure.clone(); + self.closure.set(closure); + LockCell::new(new_closure) + }, + } + } } #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)] @@ -51,13 +70,13 @@ struct Edge { target: Index, } -impl TransitiveRelation { +impl TransitiveRelation { pub fn new() -> TransitiveRelation { TransitiveRelation { elements: vec![], map: FxHashMap(), edges: vec![], - closure: RefCell::new(None), + closure: LockCell::new(None), } } @@ -72,7 +91,7 @@ impl TransitiveRelation { fn add_index(&mut self, a: T) -> Index { let &mut TransitiveRelation { ref mut elements, - ref closure, + ref mut closure, ref mut map, .. } = self; @@ -82,7 +101,7 @@ impl TransitiveRelation { elements.push(a); // if we changed the dimensions, clear the cache - *closure.borrow_mut() = None; + closure.set_mut(None); Index(elements.len() - 1) }) @@ -122,7 +141,7 @@ impl TransitiveRelation { self.edges.push(edge); // added an edge, clear the cache - *self.closure.borrow_mut() = None; + self.closure.set_mut(None); } } @@ -293,13 +312,14 @@ impl TransitiveRelation { fn with_closure(&self, op: OP) -> R where OP: FnOnce(&BitMatrix) -> R { - let mut closure_cell = self.closure.borrow_mut(); - let mut closure = closure_cell.take(); + let mut closure = self.closure.take(); if closure.is_none() { closure = Some(self.compute_closure()); } let result = op(closure.as_ref().unwrap()); - *closure_cell = closure; + // This is thread-safe. The closure we restore cannot be outdated since + // only mutable references modify the relation + self.closure.set(closure); result } @@ -380,7 +400,7 @@ impl Decodable for TransitiveRelation .enumerate() .map(|(index, elem)| (elem.clone(), Index(index))) .collect(); - Ok(TransitiveRelation { elements, edges, map, closure: RefCell::new(None) }) + Ok(TransitiveRelation { elements, edges, map, closure: LockCell::new(None) }) }) } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index f7c03fde222e8..ce5ef91f20f4d 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -22,7 +22,7 @@ use rustc::lint; use rustc::middle::{self, stability, reachable}; use rustc::middle::cstore::CrateStore; use rustc::middle::privacy::AccessLevels; -use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas}; +use rustc::ty::{self, TyCtxt, Resolutions, AllArenas}; use rustc::traits; use rustc::util::common::{ErrorReported, time}; use rustc_allocator as allocator; @@ -51,7 +51,7 @@ use std::fs; use std::io::{self, Write}; use std::iter; use std::path::{Path, PathBuf}; -use std::rc::Rc; +use std::sync::Arc; use std::sync::mpsc; use syntax::{ast, diagnostics, visit}; use syntax::attr; @@ -60,7 +60,6 @@ use syntax::parse::{self, PResult}; use syntax::util::node_count::NodeCounter; use syntax; use syntax_ext; -use arena::DroplessArena; use derive_registrar; @@ -166,8 +165,7 @@ pub fn compile_input(sess: &Session, return Ok(()) } - let arena = DroplessArena::new(); - let arenas = GlobalArenas::new(); + let arenas = AllArenas::new(); // Construct the HIR map let hir_map = time(sess.time_passes(), @@ -182,7 +180,6 @@ pub fn compile_input(sess: &Session, sess, outdir, output, - &arena, &arenas, &cstore, &hir_map, @@ -211,7 +208,6 @@ pub fn compile_input(sess: &Session, hir_map, analysis, resolutions, - &arena, &arenas, &crate_name, &outputs, @@ -396,8 +392,7 @@ pub struct CompileState<'a, 'tcx: 'a> { pub output_filenames: Option<&'a OutputFilenames>, pub out_dir: Option<&'a Path>, pub out_file: Option<&'a Path>, - pub arena: Option<&'tcx DroplessArena>, - pub arenas: Option<&'tcx GlobalArenas<'tcx>>, + pub arenas: Option<&'tcx AllArenas<'tcx>>, pub expanded_crate: Option<&'a ast::Crate>, pub hir_crate: Option<&'a hir::Crate>, pub hir_map: Option<&'a hir_map::Map<'tcx>>, @@ -417,7 +412,6 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { session, out_dir: out_dir.as_ref().map(|s| &**s), out_file: None, - arena: None, arenas: None, krate: None, registry: None, @@ -472,8 +466,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { session: &'tcx Session, out_dir: &'a Option, out_file: &'a Option, - arena: &'tcx DroplessArena, - arenas: &'tcx GlobalArenas<'tcx>, + arenas: &'tcx AllArenas<'tcx>, cstore: &'tcx CStore, hir_map: &'a hir_map::Map<'tcx>, analysis: &'a ty::CrateAnalysis, @@ -485,7 +478,6 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { -> Self { CompileState { crate_name: Some(crate_name), - arena: Some(arena), arenas: Some(arenas), cstore: Some(cstore), hir_map: Some(hir_map), @@ -891,7 +883,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, expanded_crate: krate, defs: resolver.definitions, analysis: ty::CrateAnalysis { - access_levels: Rc::new(AccessLevels::default()), + access_levels: Arc::new(AccessLevels::default()), name: crate_name.to_string(), glob_map: if resolver.make_glob_map { Some(resolver.glob_map) } else { None }, }, @@ -914,8 +906,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, hir_map: hir_map::Map<'tcx>, mut analysis: ty::CrateAnalysis, resolutions: Resolutions, - arena: &'tcx DroplessArena, - arenas: &'tcx GlobalArenas<'tcx>, + arenas: &'tcx AllArenas<'tcx>, name: &str, output_filenames: &OutputFilenames, f: F) @@ -995,7 +986,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, local_providers, extern_providers, arenas, - arena, resolutions, named_region_map, hir_map, diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index c5cce70c94566..0b4d92424b048 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -187,7 +187,7 @@ mod rustc_trans { // The FileLoader provides a way to load files from sources other than the file system. pub fn run_compiler<'a>(args: &[String], callbacks: &mut CompilerCalls<'a>, - file_loader: Option>, + file_loader: Option>, emitter_dest: Option>) -> (CompileResult, Option) { @@ -230,7 +230,7 @@ pub fn run_compiler<'a>(args: &[String], let cstore = Rc::new(CStore::new(DefaultTransCrate::metadata_loader())); let loader = file_loader.unwrap_or(box RealFileLoader); - let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping())); + let codemap = Arc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping())); let mut sess = session::build_session_with_codemap( sopts, input_file_path, descriptions, codemap, emitter_dest, ); @@ -577,7 +577,6 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { &state.expanded_crate.take().unwrap(), state.crate_name.unwrap(), ppm, - state.arena.unwrap(), state.arenas.unwrap(), state.output_filenames.unwrap(), opt_uii.clone(), diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index e6d89f77f2163..260c98b27bff9 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -17,7 +17,7 @@ use self::NodesMatchingUII::*; use {abort_on_err, driver}; -use rustc::ty::{self, TyCtxt, GlobalArenas, Resolutions}; +use rustc::ty::{self, TyCtxt, Resolutions, AllArenas}; use rustc::cfg; use rustc::cfg::graphviz::LabelledCFG; use rustc::middle::cstore::CrateStore; @@ -51,8 +51,6 @@ use rustc::hir::map::blocks; use rustc::hir; use rustc::hir::print as pprust_hir; -use arena::DroplessArena; - #[derive(Copy, Clone, PartialEq, Debug)] pub enum PpSourceMode { PpmNormal, @@ -202,8 +200,7 @@ impl PpSourceMode { hir_map: &hir_map::Map<'tcx>, analysis: &ty::CrateAnalysis, resolutions: &Resolutions, - arena: &'tcx DroplessArena, - arenas: &'tcx GlobalArenas<'tcx>, + arenas: &'tcx AllArenas<'tcx>, output_filenames: &OutputFilenames, id: &str, f: F) @@ -232,7 +229,6 @@ impl PpSourceMode { hir_map.clone(), analysis.clone(), resolutions.clone(), - arena, arenas, id, output_filenames, @@ -900,8 +896,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, krate: &ast::Crate, crate_name: &str, ppm: PpMode, - arena: &'tcx DroplessArena, - arenas: &'tcx GlobalArenas<'tcx>, + arenas: &'tcx AllArenas<'tcx>, output_filenames: &OutputFilenames, opt_uii: Option, ofile: Option<&Path>) { @@ -912,7 +907,6 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, analysis, resolutions, crate_name, - arena, arenas, output_filenames, ppm, @@ -951,7 +945,6 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, hir_map, analysis, resolutions, - arena, arenas, output_filenames, crate_name, @@ -976,7 +969,6 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, hir_map, analysis, resolutions, - arena, arenas, output_filenames, crate_name, @@ -1020,8 +1012,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, analysis: &ty::CrateAnalysis, resolutions: &Resolutions, crate_name: &str, - arena: &'tcx DroplessArena, - arenas: &'tcx GlobalArenas<'tcx>, + arenas: &'tcx AllArenas<'tcx>, output_filenames: &OutputFilenames, ppm: PpMode, uii: Option, @@ -1041,7 +1032,6 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, hir_map.clone(), analysis.clone(), resolutions.clone(), - arena, arenas, crate_name, output_filenames, diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 0e39f29204d1e..dc5b6637a74ff 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -20,7 +20,7 @@ use styled_buffer::StyledBuffer; use std::borrow::Cow; use std::io::prelude::*; use std::io; -use std::rc::Rc; +use std::sync::Arc; use term; use std::collections::HashMap; use std::cmp::min; @@ -106,19 +106,19 @@ impl ColorConfig { pub struct EmitterWriter { dst: Destination, - cm: Option>, + cm: Option>, short_message: bool, } struct FileWithAnnotatedLines { - file: Rc, + file: Arc, lines: Vec, multiline_depth: usize, } impl EmitterWriter { pub fn stderr(color_config: ColorConfig, - code_map: Option>, + code_map: Option>, short_message: bool) -> EmitterWriter { if color_config.use_color() { @@ -138,7 +138,7 @@ impl EmitterWriter { } pub fn new(dst: Box, - code_map: Option>, + code_map: Option>, short_message: bool) -> EmitterWriter { EmitterWriter { @@ -150,7 +150,7 @@ impl EmitterWriter { fn preprocess_annotations(&mut self, msp: &MultiSpan) -> Vec { fn add_annotation_to_file(file_vec: &mut Vec, - file: Rc, + file: Arc, line_index: usize, ann: Annotation) { @@ -282,7 +282,7 @@ impl EmitterWriter { fn render_source_line(&self, buffer: &mut StyledBuffer, - file: Rc, + file: Arc, line: &Line, width_offset: usize, code_offset: usize) -> Vec<(usize, Style)> { diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 7bf64d2432571..13165b0955f9c 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -33,14 +33,16 @@ use self::Level::*; use emitter::{Emitter, EmitterWriter}; +use rustc_data_structures::lock::{Lock, LockCell}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stable_hasher::StableHasher; use std::borrow::Cow; -use std::cell::{RefCell, Cell}; use std::mem; -use std::rc::Rc; +use std::sync::Arc; use std::{error, fmt}; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering::SeqCst; mod diagnostic; mod diagnostic_builder; @@ -113,12 +115,13 @@ pub trait CodeMapper { fn span_to_filename(&self, sp: Span) -> FileName; fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option; fn call_span_if_macro(&self, sp: Span) -> Span; - fn ensure_filemap_source_present(&self, file_map: Rc) -> bool; + fn ensure_filemap_source_present(&self, file_map: Arc) -> bool; } impl CodeSuggestion { /// Returns the assembled code suggestions and whether they should be shown with an underline. - pub fn splice_lines(&self, cm: &CodeMapper) -> Vec<(String, Vec)> { + pub fn splice_lines(&self, cm: &(CodeMapper + Send + Sync)) + -> Vec<(String, Vec)> { use syntax_pos::{CharPos, Loc, Pos}; fn push_trailing(buf: &mut String, @@ -247,25 +250,25 @@ pub use diagnostic_builder::DiagnosticBuilder; /// (fatal, bug, unimpl) may cause immediate exit, /// others log errors for later reporting. pub struct Handler { - err_count: Cell, - emitter: RefCell>, + err_count: AtomicUsize, + emitter: Lock>, pub can_emit_warnings: bool, treat_err_as_bug: bool, - continue_after_error: Cell, - delayed_span_bug: RefCell>, - tracked_diagnostics: RefCell>>, + continue_after_error: LockCell, + delayed_span_bug: Lock>, + tracked_diagnostics: Lock>>, // This set contains a hash of every diagnostic that has been emitted by // this handler. These hashes is used to avoid emitting the same error // twice. - emitted_diagnostics: RefCell>, + emitted_diagnostics: Lock>, } impl Handler { pub fn with_tty_emitter(color_config: ColorConfig, can_emit_warnings: bool, treat_err_as_bug: bool, - cm: Option>) + cm: Option>) -> Handler { let emitter = Box::new(EmitterWriter::stderr(color_config, cm, false)); Handler::with_emitter(can_emit_warnings, treat_err_as_bug, emitter) @@ -273,17 +276,17 @@ impl Handler { pub fn with_emitter(can_emit_warnings: bool, treat_err_as_bug: bool, - e: Box) + e: Box) -> Handler { Handler { - err_count: Cell::new(0), - emitter: RefCell::new(e), + err_count: AtomicUsize::new(0), + emitter: Lock::new(e), can_emit_warnings, treat_err_as_bug, - continue_after_error: Cell::new(true), - delayed_span_bug: RefCell::new(None), - tracked_diagnostics: RefCell::new(None), - emitted_diagnostics: RefCell::new(FxHashSet()), + continue_after_error: LockCell::new(true), + delayed_span_bug: Lock::new(None), + tracked_diagnostics: Lock::new(None), + emitted_diagnostics: Lock::new(FxHashSet()), } } @@ -294,7 +297,7 @@ impl Handler { // NOTE: DO NOT call this function from rustc, as it relies on `err_count` being non-zero // if an error happened to avoid ICEs. This function should only be called from tools. pub fn reset_err_count(&self) { - self.err_count.set(0); + self.err_count.store(0, SeqCst); } pub fn struct_dummy<'a>(&'a self) -> DiagnosticBuilder<'a> { @@ -490,19 +493,19 @@ impl Handler { fn bump_err_count(&self) { self.panic_if_treat_err_as_bug(); - self.err_count.set(self.err_count.get() + 1); + self.err_count.fetch_add(1, SeqCst); } pub fn err_count(&self) -> usize { - self.err_count.get() + self.err_count.load(SeqCst) } pub fn has_errors(&self) -> bool { - self.err_count.get() > 0 + self.err_count() > 0 } pub fn abort_if_errors(&self) { let s; - match self.err_count.get() { + match self.err_count() { 0 => { if let Some(bug) = self.delayed_span_bug.borrow_mut().take() { DiagnosticBuilder::new_diagnostic(self, bug).emit(); @@ -511,7 +514,7 @@ impl Handler { } 1 => s = "aborting due to previous error".to_string(), _ => { - s = format!("aborting due to {} previous errors", self.err_count.get()); + s = format!("aborting due to {} previous errors", self.err_count()); } } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 155097cdbe26c..c8fdd3d9909cf 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -14,6 +14,7 @@ use cstore::{self, CStore, CrateSource, MetadataBlob}; use locator::{self, CratePaths}; use native_libs::relevant_lib; use schema::CrateRoot; +use rustc_data_structures::lock::{RwLock, Lock, LockCell}; use rustc::hir::def_id::{CrateNum, DefIndex, CRATE_DEF_INDEX}; use rustc::hir::svh::Svh; @@ -29,10 +30,9 @@ use rustc::util::common::record_time; use rustc::util::nodemap::FxHashSet; use rustc::hir::map::Definitions; -use std::cell::{RefCell, Cell}; +use std::sync::Arc; use std::ops::Deref; use std::path::PathBuf; -use std::rc::Rc; use std::{cmp, fs}; use syntax::ast; @@ -87,7 +87,7 @@ struct ExtensionCrate { } enum PMDSource { - Registered(Rc), + Registered(Arc), Owned(Library), } @@ -230,7 +230,7 @@ impl<'a> CrateLoader<'a> { span: Span, lib: Library, dep_kind: DepKind) - -> (CrateNum, Rc) { + -> (CrateNum, Arc) { info!("register crate `extern crate {} as {}`", name, ident); let crate_root = lib.metadata.get_root(); self.verify_no_symbol_conflicts(span, &crate_root); @@ -272,8 +272,8 @@ impl<'a> CrateLoader<'a> { let mut cmeta = cstore::CrateMetadata { name, - extern_crate: Cell::new(None), - def_path_table: Rc::new(def_path_table), + extern_crate: LockCell::new(None), + def_path_table: Arc::new(def_path_table), exported_symbols, trait_impls, proc_macros: crate_root.macro_derive_registrar.map(|_| { @@ -281,11 +281,11 @@ impl<'a> CrateLoader<'a> { }), root: crate_root, blob: metadata, - cnum_map: RefCell::new(cnum_map), + cnum_map: Lock::new(cnum_map), cnum, - codemap_import_info: RefCell::new(vec![]), - attribute_cache: RefCell::new([Vec::new(), Vec::new()]), - dep_kind: Cell::new(dep_kind), + codemap_import_info: RwLock::new(vec![]), + attribute_cache: Lock::new([Vec::new(), Vec::new()]), + dep_kind: LockCell::new(dep_kind), source: cstore::CrateSource { dylib, rlib, @@ -310,7 +310,7 @@ impl<'a> CrateLoader<'a> { cmeta.dllimport_foreign_items = dllimports; - let cmeta = Rc::new(cmeta); + let cmeta = Arc::new(cmeta); self.cstore.set_crate_data(cnum, cmeta.clone()); (cnum, cmeta) } @@ -323,7 +323,7 @@ impl<'a> CrateLoader<'a> { span: Span, path_kind: PathKind, mut dep_kind: DepKind) - -> (CrateNum, Rc) { + -> (CrateNum, Arc) { info!("resolving crate `extern crate {} as {}`", name, ident); let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) { LoadResult::Previous(cnum) @@ -552,7 +552,7 @@ impl<'a> CrateLoader<'a> { /// custom derive (and other macro-1.1 style features) are implemented via /// executables and custom IPC. fn load_derive_macros(&mut self, root: &CrateRoot, dylib: Option, span: Span) - -> Vec<(ast::Name, Rc)> { + -> Vec<(ast::Name, Arc)> { use std::{env, mem}; use proc_macro::TokenStream; use proc_macro::__internal::Registry; @@ -581,7 +581,7 @@ impl<'a> CrateLoader<'a> { mem::transmute::<*mut u8, fn(&mut Registry)>(sym) }; - struct MyRegistrar(Vec<(ast::Name, Rc)>); + struct MyRegistrar(Vec<(ast::Name, Arc)>); impl Registry for MyRegistrar { fn register_custom_derive(&mut self, @@ -591,7 +591,7 @@ impl<'a> CrateLoader<'a> { let attrs = attributes.iter().cloned().map(Symbol::intern).collect::>(); let derive = ProcMacroDerive::new(expand, attrs.clone()); let derive = SyntaxExtension::ProcMacroDerive(Box::new(derive), attrs); - self.0.push((Symbol::intern(trait_name), Rc::new(derive))); + self.0.push((Symbol::intern(trait_name), Arc::new(derive))); } fn register_attr_proc_macro(&mut self, @@ -600,7 +600,7 @@ impl<'a> CrateLoader<'a> { let expand = SyntaxExtension::AttrProcMacro( Box::new(AttrProcMacro { inner: expand }) ); - self.0.push((Symbol::intern(name), Rc::new(expand))); + self.0.push((Symbol::intern(name), Arc::new(expand))); } fn register_bang_proc_macro(&mut self, @@ -609,7 +609,7 @@ impl<'a> CrateLoader<'a> { let expand = SyntaxExtension::ProcMacro( Box::new(BangProcMacro { inner: expand }) ); - self.0.push((Symbol::intern(name), Rc::new(expand))); + self.0.push((Symbol::intern(name), Arc::new(expand))); } } diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index a86b55e269d41..81a9d5dcfb9d6 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -22,8 +22,8 @@ use rustc_back::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap}; -use std::cell::{RefCell, Cell}; -use std::rc::Rc; +use rustc_data_structures::lock::{RwLock, Lock, LockCell}; +use std::sync::Arc; use owning_ref::ErasedBoxRef; use syntax::{ast, attr}; use syntax::ext::base::SyntaxExtension; @@ -52,7 +52,7 @@ pub struct ImportedFileMap { /// The end of this FileMap within the codemap of its original crate pub original_end_pos: syntax_pos::BytePos, /// The imported FileMap's representation within the local codemap - pub translated_filemap: Rc, + pub translated_filemap: Arc, } pub struct CrateMetadata { @@ -61,13 +61,13 @@ pub struct CrateMetadata { /// Information about the extern crate that caused this crate to /// be loaded. If this is `None`, then the crate was injected /// (e.g., by the allocator) - pub extern_crate: Cell>, + pub extern_crate: LockCell>, pub blob: MetadataBlob, - pub cnum_map: RefCell, + pub cnum_map: Lock, pub cnum: CrateNum, - pub codemap_import_info: RefCell>, - pub attribute_cache: RefCell<[Vec>>; 2]>, + pub codemap_import_info: RwLock>, + pub attribute_cache: Lock<[Vec>>; 2]>, pub root: schema::CrateRoot, @@ -76,32 +76,32 @@ pub struct CrateMetadata { /// hashmap, which gives the reverse mapping. This allows us to /// quickly retrace a `DefPath`, which is needed for incremental /// compilation support. - pub def_path_table: Rc, + pub def_path_table: Arc, pub exported_symbols: FxHashSet, pub trait_impls: FxHashMap<(u32, DefIndex), schema::LazySeq>, - pub dep_kind: Cell, + pub dep_kind: LockCell, pub source: CrateSource, - pub proc_macros: Option)>>, + pub proc_macros: Option)>>, // Foreign items imported from a dylib (Windows only) pub dllimport_foreign_items: FxHashSet, } pub struct CStore { - metas: RefCell>>, + metas: RwLock>>, /// Map from NodeId's of local extern crate statements to crate numbers - extern_mod_crate_map: RefCell>, + extern_mod_crate_map: Lock>, pub metadata_loader: Box, } impl CStore { pub fn new(metadata_loader: Box) -> CStore { CStore { - metas: RefCell::new(FxHashMap()), - extern_mod_crate_map: RefCell::new(FxHashMap()), + metas: RwLock::new(FxHashMap()), + extern_mod_crate_map: Lock::new(FxHashMap()), metadata_loader, } } @@ -110,16 +110,16 @@ impl CStore { CrateNum::new(self.metas.borrow().len() + 1) } - pub fn get_crate_data(&self, cnum: CrateNum) -> Rc { + pub fn get_crate_data(&self, cnum: CrateNum) -> Arc { self.metas.borrow().get(&cnum).unwrap().clone() } - pub fn set_crate_data(&self, cnum: CrateNum, data: Rc) { + pub fn set_crate_data(&self, cnum: CrateNum, data: Arc) { self.metas.borrow_mut().insert(cnum, data); } pub fn iter_crate_data(&self, mut i: I) - where I: FnMut(CrateNum, &Rc) + where I: FnMut(CrateNum, &Arc) { for (&k, v) in self.metas.borrow().iter() { i(k, v); diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 8dcfb4c34b5b2..6228d9cdf136d 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -31,7 +31,7 @@ use rustc::hir::map::definitions::DefPathTable; use rustc::util::nodemap::{NodeSet, DefIdMap}; use std::any::Any; -use std::rc::Rc; +use std::sync::Arc; use syntax::ast; use syntax::attr; @@ -112,12 +112,12 @@ provide! { <'tcx> tcx, def_id, other, cdata, let _ = cdata; tcx.calculate_dtor(def_id, &mut |_,_| Ok(())) } - variances_of => { Rc::new(cdata.get_item_variances(def_id.index)) } + variances_of => { Arc::new(cdata.get_item_variances(def_id.index)) } associated_item_def_ids => { let mut result = vec![]; cdata.each_child_of_item(def_id.index, |child| result.push(child.def.def_id()), tcx.sess); - Rc::new(result) + Arc::new(result) } associated_item => { cdata.get_associated_item(def_id.index) } impl_trait_ref => { cdata.get_impl_trait(def_id.index, tcx) } @@ -138,12 +138,12 @@ provide! { <'tcx> tcx, def_id, other, cdata, } generator_sig => { cdata.generator_sig(def_id.index, tcx) } mir_const_qualif => { - (cdata.mir_const_qualif(def_id.index), Rc::new(IdxSetBuf::new_empty(0))) + (cdata.mir_const_qualif(def_id.index), Arc::new(IdxSetBuf::new_empty(0))) } typeck_tables_of => { cdata.item_body_tables(def_id.index, tcx) } closure_kind => { cdata.closure_kind(def_id.index) } fn_sig => { cdata.fn_sig(def_id.index, tcx) } - inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) } + inherent_impls => { Arc::new(cdata.get_inherent_implementations_for_type(def_id.index)) } is_const_fn => { cdata.is_const_fn(def_id.index) } is_foreign_item => { cdata.is_foreign_item(def_id.index) } is_auto_impl => { cdata.is_auto_impl(def_id.index) } @@ -172,18 +172,18 @@ provide! { <'tcx> tcx, def_id, other, cdata, } is_mir_available => { cdata.is_item_mir_available(def_id.index) } - dylib_dependency_formats => { Rc::new(cdata.get_dylib_dependency_formats()) } + dylib_dependency_formats => { Arc::new(cdata.get_dylib_dependency_formats()) } is_panic_runtime => { cdata.is_panic_runtime(tcx.sess) } is_compiler_builtins => { cdata.is_compiler_builtins(tcx.sess) } has_global_allocator => { cdata.has_global_allocator() } is_sanitizer_runtime => { cdata.is_sanitizer_runtime(tcx.sess) } is_profiler_runtime => { cdata.is_profiler_runtime(tcx.sess) } panic_strategy => { cdata.panic_strategy() } - extern_crate => { Rc::new(cdata.extern_crate.get()) } + extern_crate => { Arc::new(cdata.extern_crate.get()) } is_no_builtins => { cdata.is_no_builtins(tcx.sess) } impl_defaultness => { cdata.get_impl_defaultness(def_id.index) } - exported_symbol_ids => { Rc::new(cdata.get_exported_symbols()) } - native_libraries => { Rc::new(cdata.get_native_libraries(tcx.sess)) } + exported_symbol_ids => { Arc::new(cdata.get_exported_symbols()) } + native_libraries => { Arc::new(cdata.get_native_libraries(tcx.sess)) } plugin_registrar_fn => { cdata.root.plugin_registrar_fn.map(|index| { DefId { krate: def_id.krate, index } @@ -202,13 +202,13 @@ provide! { <'tcx> tcx, def_id, other, cdata, let mut result = vec![]; let filter = Some(other); cdata.get_implementations_for_trait(filter, &mut result); - Rc::new(result) + Arc::new(result) } all_trait_implementations => { let mut result = vec![]; cdata.get_implementations_for_trait(None, &mut result); - Rc::new(result) + Arc::new(result) } is_dllimport_foreign_item => { @@ -220,10 +220,10 @@ provide! { <'tcx> tcx, def_id, other, cdata, item_children => { let mut result = vec![]; cdata.each_child_of_item(def_id.index, |child| result.push(child), tcx.sess); - Rc::new(result) + Arc::new(result) } - defined_lang_items => { Rc::new(cdata.get_lang_items()) } - missing_lang_items => { Rc::new(cdata.get_missing_lang_items()) } + defined_lang_items => { Arc::new(cdata.get_lang_items()) } + missing_lang_items => { Arc::new(cdata.get_missing_lang_items()) } extern_const_body => { debug!("item_body({:?}): inlining item", def_id); @@ -237,7 +237,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, } } - used_crate_source => { Rc::new(cdata.source.clone()) } + used_crate_source => { Arc::new(cdata.source.clone()) } has_copy_closures => { cdata.has_copy_closures(tcx.sess) } has_clone_closures => { cdata.has_clone_closures(tcx.sess) } @@ -279,11 +279,11 @@ pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) { }, native_libraries: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Rc::new(native_libs::collect(tcx)) + Arc::new(native_libs::collect(tcx)) }, link_args: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Rc::new(link_args::collect(tcx)) + Arc::new(link_args::collect(tcx)) }, // Returns a map from a sufficiently visible external item (i.e. an @@ -340,7 +340,7 @@ pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) { } } - Rc::new(visible_parent_map) + Arc::new(visible_parent_map) }, ..*providers @@ -348,7 +348,7 @@ pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) { } impl CrateStore for cstore::CStore { - fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc { + fn crate_data_as_rc_any(&self, krate: CrateNum) -> Arc { self.get_crate_data(krate) } @@ -421,7 +421,7 @@ impl CrateStore for cstore::CStore { self.get_crate_data(def.krate).def_path_hash(def.index) } - fn def_path_table(&self, cnum: CrateNum) -> Rc { + fn def_path_table(&self, cnum: CrateNum) -> Arc { self.get_crate_data(cnum).def_path_table.clone() } @@ -445,7 +445,7 @@ impl CrateStore for cstore::CStore { } else if data.name == "proc_macro" && self.get_crate_data(id.krate).item_name(id.index) == "quote" { let ext = SyntaxExtension::ProcMacro(Box::new(::proc_macro::__internal::Quoter)); - return LoadedMacro::ProcMacro(Rc::new(ext)); + return LoadedMacro::ProcMacro(Arc::new(ext)); } let (name, def) = data.get_macro(id.index); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index e63037f4da1ef..e7e09aa0a8078 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -13,6 +13,7 @@ use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary}; use schema::*; +use rustc_data_structures::lock::ReadGuard; use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc::hir; @@ -32,11 +33,11 @@ use rustc::util::nodemap::DefIdSet; use rustc::mir::Mir; use std::borrow::Cow; -use std::cell::Ref; use std::collections::BTreeMap; use std::io; use std::mem; use std::rc::Rc; +use std::sync::Arc; use std::str; use std::u32; @@ -926,11 +927,11 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Rc<[ast::Attribute]> { + pub fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Arc<[ast::Attribute]> { let (node_as, node_index) = (node_id.address_space().index(), node_id.as_array_index()); if self.is_proc_macro(node_id) { - return Rc::new([]); + return Arc::new([]); } if let Some(&Some(ref val)) = @@ -946,7 +947,7 @@ impl<'a, 'tcx> CrateMetadata { if def_key.disambiguated_data.data == DefPathData::StructCtor { item = self.entry(def_key.parent.unwrap()); } - let result: Rc<[ast::Attribute]> = Rc::from(self.get_attributes(&item, sess)); + let result: Arc<[ast::Attribute]> = Arc::from(self.get_attributes(&item, sess)); let vec_ = &mut self.attribute_cache.borrow_mut()[node_as]; if vec_.len() < node_index + 1 { vec_.resize(node_index + 1, None); @@ -1188,7 +1189,7 @@ impl<'a, 'tcx> CrateMetadata { /// for items inlined from other crates. pub fn imported_filemaps(&'a self, local_codemap: &codemap::CodeMap) - -> Ref<'a, Vec> { + -> ReadGuard<'a, Vec> { { let filemaps = self.codemap_import_info.borrow(); if !filemaps.is_empty() { diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index d5eee14bf506b..b7c6fc4739d50 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -35,7 +35,7 @@ use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque}; use std::io::prelude::*; use std::io::Cursor; use std::path::Path; -use std::rc::Rc; +use std::sync::Arc; use std::u32; use syntax::ast::{self, CRATE_NODE_ID}; use syntax::codemap::Spanned; @@ -273,7 +273,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { .to_string_lossy() .into_owned(); adapted.name = abs_path; - Rc::new(adapted) + Arc::new(adapted) } }) .collect::>(); diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 50264238aacb2..50f1acab75b37 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -30,7 +30,7 @@ use syntax::ast; use syntax::symbol::Symbol; use rustc::hir; use rustc_const_math::{ConstInt, ConstUsize}; -use std::rc::Rc; +use std::sync::Arc; #[derive(Clone)] pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { @@ -43,7 +43,7 @@ pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { /// Identity `Substs` for use with const-evaluation. pub identity_substs: &'gcx Substs<'gcx>, - pub region_scope_tree: Rc, + pub region_scope_tree: Arc, pub tables: &'a ty::TypeckTables<'gcx>, /// This is `Constness::Const` if we are compiling a `static`, diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index cbf1b0b089917..7b3d7f1425473 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -22,7 +22,7 @@ use rustc::mir::visit::{LvalueContext, Visitor}; use syntax::ast; -use std::rc::Rc; +use std::sync::Arc; pub struct UnsafetyChecker<'a, 'tcx: 'a> { @@ -310,8 +310,8 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) ClearOnDecode::Clear => { debug!("unsafety_violations: {:?} - remote, skipping", def_id); return UnsafetyCheckResult { - violations: Rc::new([]), - unsafe_blocks: Rc::new([]) + violations: Arc::new([]), + unsafe_blocks: Arc::new([]) } } }; diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 441f9be9be1f4..9628799d6cda8 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -17,8 +17,8 @@ use rustc::ty::steal::Steal; use rustc::hir; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::util::nodemap::DefIdSet; +use std::sync::Arc; use std::borrow::Cow; -use std::rc::Rc; use syntax::ast; use syntax_pos::Span; @@ -64,7 +64,7 @@ fn is_mir_available<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> boo /// Finds the full set of def-ids within the current crate that have /// MIR associated with them. fn mir_keys<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, krate: CrateNum) - -> Rc { + -> Arc { assert_eq!(krate, LOCAL_CRATE); let mut set = DefIdSet(); @@ -99,7 +99,7 @@ fn mir_keys<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, krate: CrateNum) set: &mut set, }.as_deep_visitor()); - Rc::new(set) + Arc::new(set) } fn mir_built<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Steal> { diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index ab29134c32541..8ff2bd2e2d954 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -34,7 +34,7 @@ use syntax::feature_gate::UnstableFeatures; use syntax_pos::{Span, DUMMY_SP}; use std::fmt; -use std::rc::Rc; +use std::sync::Arc; use std::usize; use transform::{MirPass, MirSource}; @@ -287,7 +287,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { } /// Qualify a whole const, static initializer or const fn. - fn qualify_const(&mut self) -> (Qualif, Rc>) { + fn qualify_const(&mut self) -> (Qualif, Arc>) { debug!("qualifying {} {:?}", self.mode, self.def_id); let mir = self.mir; @@ -402,7 +402,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { } } - (self.qualif, Rc::new(promoted_temps)) + (self.qualif, Arc::new(promoted_temps)) } } @@ -931,7 +931,7 @@ pub fn provide(providers: &mut Providers) { fn mir_const_qualif<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> (u8, Rc>) { + -> (u8, Arc>) { // NB: This `borrow()` is guaranteed to be valid (i.e., the value // cannot yet be stolen), because `mir_validated()`, which steals // from `mir_const(), forces this query to execute before @@ -940,7 +940,7 @@ fn mir_const_qualif<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if mir.return_ty.references_error() { tcx.sess.delay_span_bug(mir.span, "mir_const_qualif: Mir had errors"); - return (Qualif::NOT_CONST.bits(), Rc::new(IdxSetBuf::new_empty(0))); + return (Qualif::NOT_CONST.bits(), Arc::new(IdxSetBuf::new_empty(0))); } let mut qualifier = Qualifier::new(tcx, def_id, mir, Mode::Const); diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 776b5f3c984f1..f1ed42a5835d1 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -45,7 +45,7 @@ use rustc::util::common::ErrorReported; use rustc::util::nodemap::{ItemLocalSet, NodeSet}; use rustc::lint::builtin::CONST_ERR; use rustc::hir::{self, PatKind, RangeEnd}; -use std::rc::Rc; +use std::sync::Arc; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; @@ -83,7 +83,7 @@ fn const_is_rvalue_promotable_to_static<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn rvalue_promotable_map<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Rc + -> Arc { let outer_def_id = tcx.closure_base_def_id(def_id); if outer_def_id != def_id { @@ -108,7 +108,7 @@ fn rvalue_promotable_map<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let body_id = tcx.hir.body_owned_by(node_id); visitor.visit_nested_body(body_id); - Rc::new(visitor.result) + Arc::new(visitor.result) } struct CheckCrateVisitor<'a, 'tcx: 'a> { diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 630260feed789..43c98093d4399 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -37,7 +37,7 @@ use syntax_pos::Span; use std::cmp; use std::mem::replace; -use std::rc::Rc; +use std::sync::Arc; mod diagnostics; @@ -1582,13 +1582,13 @@ pub fn provide(providers: &mut Providers) { }; } -pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Rc { +pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Arc { tcx.privacy_access_levels(LOCAL_CRATE) } fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, krate: CrateNum) - -> Rc { + -> Arc { assert_eq!(krate, LOCAL_CRATE); let krate = tcx.hir.krate(); @@ -1661,7 +1661,7 @@ fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor)); } - Rc::new(visitor.access_levels) + Arc::new(visitor.access_levels) } __build_diagnostic_array! { librustc_privacy, DIAGNOSTICS } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index b30fc38fcbcdf..3fab6a9a7029f 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -27,7 +27,7 @@ use rustc::hir::def_id::{BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, LOCAL_CRATE, Def use rustc::ty; use std::cell::Cell; -use std::rc::Rc; +use std::sync::Arc; use syntax::ast::{Name, Ident}; use syntax::attr; @@ -565,7 +565,7 @@ impl<'a> Resolver<'a> { } } - pub fn get_macro(&mut self, def: Def) -> Rc { + pub fn get_macro(&mut self, def: Def) -> Arc { let def_id = match def { Def::Macro(def_id, ..) => def_id, _ => panic!("Expected Def::Macro(..)"), @@ -579,7 +579,7 @@ impl<'a> Resolver<'a> { LoadedMacro::ProcMacro(ext) => return ext, }; - let ext = Rc::new(macro_rules::compile(&self.session.parse_sess, + let ext = Arc::new(macro_rules::compile(&self.session.parse_sess, &self.session.features, ¯o_def)); self.macro_map.insert(def_id, ext.clone()); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8207057fd0aae..5af1db4cd8358 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -67,7 +67,7 @@ use std::cmp; use std::collections::BTreeSet; use std::fmt; use std::mem::replace; -use std::rc::Rc; +use std::sync::Arc; use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver}; use macros::{InvocationData, LegacyBinding, LegacyScope, MacroBinding}; @@ -1091,7 +1091,7 @@ impl<'a> NameBinding<'a> { } } - fn get_macro(&self, resolver: &mut Resolver<'a>) -> Rc { + fn get_macro(&self, resolver: &mut Resolver<'a>) -> Arc { resolver.get_macro(self.def_ignoring_ambiguity()) } @@ -1290,7 +1290,7 @@ pub struct Resolver<'a> { macro_names: FxHashSet, global_macros: FxHashMap>, lexical_macro_resolutions: Vec<(Ident, &'a Cell>)>, - macro_map: FxHashMap>, + macro_map: FxHashMap>, macro_defs: FxHashMap, local_macro_def_scopes: FxHashMap>, macro_exports: Vec, diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index a52e6fcad1481..a04fb462d9353 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -40,7 +40,7 @@ use syntax_pos::{Span, DUMMY_SP}; use std::cell::Cell; use std::mem; -use std::rc::Rc; +use std::sync::Arc; #[derive(Clone)] pub struct InvocationData<'a> { @@ -177,7 +177,7 @@ impl<'a> base::Resolver for Resolver<'a> { invocation.expansion.set(visitor.legacy_scope); } - fn add_builtin(&mut self, ident: ast::Ident, ext: Rc) { + fn add_builtin(&mut self, ident: ast::Ident, ext: Arc) { let def_id = DefId { krate: BUILTIN_MACROS_CRATE, index: DefIndex::new(self.macro_map.len()), @@ -284,7 +284,7 @@ impl<'a> base::Resolver for Resolver<'a> { } fn resolve_invoc(&mut self, invoc: &mut Invocation, scope: Mark, force: bool) - -> Result>, Determinacy> { + -> Result>, Determinacy> { let def = match invoc.kind { InvocationKind::Attr { attr: None, .. } => return Ok(None), _ => self.resolve_invoc_to_def(invoc, scope, force)?, @@ -304,7 +304,7 @@ impl<'a> base::Resolver for Resolver<'a> { } fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool) - -> Result, Determinacy> { + -> Result, Determinacy> { self.resolve_macro_to_def(scope, path, kind, force).map(|def| { self.unused_macros.remove(&def.def_id()); self.get_macro(def) @@ -724,7 +724,7 @@ impl<'a> Resolver<'a> { } let def_id = self.definitions.local_def_id(item.id); - let ext = Rc::new(macro_rules::compile(&self.session.parse_sess, + let ext = Arc::new(macro_rules::compile(&self.session.parse_sess, &self.session.features, item)); self.macro_map.insert(def_id, ext); diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index 23890905718a8..3f590ca0f643e 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::rc::Rc; use std::sync::Arc; use base; @@ -63,7 +62,7 @@ pub fn crates_export_threshold(crate_types: &[config::CrateType]) pub fn provide_local(providers: &mut Providers) { providers.exported_symbol_ids = |tcx, cnum| { let export_threshold = threshold(tcx); - Rc::new(tcx.exported_symbols(cnum) + Arc::new(tcx.exported_symbols(cnum) .iter() .filter_map(|&(_, id, level)| { id.and_then(|id| { diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index d59d8ca1a7801..48503a23bf228 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -920,7 +920,7 @@ pub fn start_async_translation(tcx: TyCtxt, crate_info, time_graph, - coordinator_send: tcx.tx_to_llvm_workers.clone(), + coordinator_send: tcx.tx_to_llvm_workers.lock().clone(), trans_worker_receive, shared_emitter_main, future: coordinator_thread, @@ -1290,7 +1290,7 @@ fn start_executing_work(tcx: TyCtxt, metadata_config: Arc, allocator_config: Arc) -> thread::JoinHandle> { - let coordinator_send = tcx.tx_to_llvm_workers.clone(); + let coordinator_send = tcx.tx_to_llvm_workers.lock().clone(); let mut exported_symbols = FxHashMap(); exported_symbols.insert(LOCAL_CRATE, tcx.exported_symbols(LOCAL_CRATE)); for &cnum in tcx.crates().iter() { @@ -2175,7 +2175,7 @@ pub fn submit_translated_module_to_llvm(tcx: TyCtxt, mtrans: ModuleTranslation, cost: u64) { let llvm_work_item = WorkItem::Optimize(mtrans); - drop(tcx.tx_to_llvm_workers.send(Box::new(Message::TranslationDone { + drop(tcx.tx_to_llvm_workers.lock().send(Box::new(Message::TranslationDone { llvm_work_item, cost, }))); diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 29394af33969f..7978d5666f003 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -72,8 +72,8 @@ pub use llvm_util::{init, target_features, print_version, print_passes, print, e use std::any::Any; use std::path::PathBuf; -use std::rc::Rc; use std::sync::mpsc; +use std::sync::Arc; use rustc::dep_graph::DepGraph; use rustc::hir::def_id::CrateNum; @@ -322,11 +322,11 @@ pub struct CrateInfo { profiler_runtime: Option, sanitizer_runtime: Option, is_no_builtins: FxHashSet, - native_libraries: FxHashMap>>, + native_libraries: FxHashMap>>, crate_name: FxHashMap, - used_libraries: Rc>, - link_args: Rc>, - used_crate_source: FxHashMap>, + used_libraries: Arc>, + link_args: Arc>, + used_crate_source: FxHashMap>, used_crates_static: Vec<(CrateNum, LibSource)>, used_crates_dynamic: Vec<(CrateNum, LibSource)>, } diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs index af1297697c241..d3991fe0d84fb 100644 --- a/src/librustc_typeck/check/generator_interior.rs +++ b/src/librustc_typeck/check/generator_interior.rs @@ -18,14 +18,14 @@ use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::{self, Pat, PatKind, Expr}; use rustc::middle::region; use rustc::ty::Ty; -use std::rc::Rc; +use std::sync::Arc; use super::FnCtxt; use util::nodemap::FxHashMap; struct InteriorVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, types: FxHashMap, usize>, - region_scope_tree: Rc, + region_scope_tree: Arc, expr_count: usize, } diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 58d72e37d51cf..30c5bb0d5ca17 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -25,7 +25,7 @@ use syntax_pos::Span; use rustc::hir; -use std::rc::Rc; +use std::sync::Arc; pub use self::MethodError::*; pub use self::CandidateSource::*; @@ -165,7 +165,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(import_id) = pick.import_id { let import_def_id = self.tcx.hir.local_def_id(import_id); debug!("used_trait_import: {:?}", import_def_id); - Rc::get_mut(&mut self.tables.borrow_mut().used_trait_imports) + Arc::get_mut(&mut self.tables.borrow_mut().used_trait_imports) .unwrap().insert(import_def_id); } @@ -364,7 +364,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(import_id) = pick.import_id { let import_def_id = self.tcx.hir.local_def_id(import_id); debug!("used_trait_import: {:?}", import_def_id); - Rc::get_mut(&mut self.tables.borrow_mut().used_trait_imports) + Arc::get_mut(&mut self.tables.borrow_mut().used_trait_imports) .unwrap().insert(import_def_id); } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 8613ec86b4a73..8b0d543fe1adf 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -21,6 +21,7 @@ use namespace::Namespace; use rustc::traits::{Obligation, SelectionContext}; use util::nodemap::FxHashSet; +use rustc_data_structures::lock::LockGuard; use syntax::ast; use errors::DiagnosticBuilder; use syntax_pos::Span; @@ -29,7 +30,6 @@ use rustc::hir; use rustc::hir::print; use rustc::infer::type_variable::TypeVariableOrigin; -use std::cell; use std::cmp::Ordering; use super::{MethodError, NoMatchData, CandidateSource}; @@ -588,7 +588,7 @@ pub fn all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> AllTraits<'a> } pub struct AllTraits<'a> { - borrow: cell::Ref<'a, Option>, + borrow: LockGuard<'a, Option>, idx: usize, } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 82d59ecfc92cf..90c01ab9692ad 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -109,7 +109,7 @@ use util::common::{ErrorReported, indenter}; use util::nodemap::{DefIdMap, DefIdSet, FxHashMap, NodeMap}; use std::cell::{Cell, RefCell, Ref, RefMut}; -use std::rc::Rc; +use std::sync::Arc; use std::collections::hash_map::Entry; use std::cmp; use std::fmt::Display; @@ -849,7 +849,7 @@ fn has_typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn used_trait_imports<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Rc { + -> Arc { tcx.typeck_tables_of(def_id).used_trait_imports.clone() } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index ad7978480a6b1..477fe63a74e6d 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -99,7 +99,7 @@ use rustc::ty::wf; use std::mem; use std::ops::Deref; -use std::rc::Rc; +use std::sync::Arc; use syntax::ast; use syntax_pos::Span; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; @@ -179,7 +179,7 @@ pub struct RegionCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { region_bound_pairs: Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>, - pub region_scope_tree: Rc, + pub region_scope_tree: Arc, free_region_map: FreeRegionMap<'tcx>, diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index ce2ac73a27e0c..32fec5b1cef31 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -23,7 +23,7 @@ use rustc::util::nodemap::DefIdSet; use syntax::ast; use syntax_pos::Span; use std::mem; -use std::rc::Rc; +use std::sync::Arc; /////////////////////////////////////////////////////////////////////////// // Entry point @@ -50,7 +50,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { wbcx.visit_generator_interiors(); let used_trait_imports = mem::replace(&mut self.tables.borrow_mut().used_trait_imports, - Rc::new(DefIdSet())); + Arc::new(DefIdSet())); debug!("used_trait_imports({:?}) = {:?}", item_def_id, used_trait_imports); wbcx.tables.used_trait_imports = used_trait_imports; diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 569b6a2febb45..dc53821c562c6 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -24,7 +24,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::{self, CrateInherentImpls, TyCtxt}; use rustc::util::nodemap::DefIdMap; -use std::rc::Rc; +use std::sync::Arc; use syntax::ast; use syntax_pos::Span; @@ -48,7 +48,7 @@ pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, /// On-demand query: yields a vector of the inherent impls for a specific type. pub fn inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty_def_id: DefId) - -> Rc> { + -> Arc> { assert!(ty_def_id.is_local()); // NB. Until we adopt the red-green dep-tracking algorithm (see @@ -67,7 +67,7 @@ pub fn inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // [the plan]: https://github.com/rust-lang/rust-roadmap/issues/4 thread_local! { - static EMPTY_DEF_ID_VEC: Rc> = Rc::new(vec![]) + static EMPTY_DEF_ID_VEC: Arc> = Arc::new(vec![]) } let result = tcx.dep_graph.with_ignore(|| { @@ -296,11 +296,11 @@ impl<'a, 'tcx> InherentCollect<'a, 'tcx> { let impl_def_id = self.tcx.hir.local_def_id(item.id); let mut rc_vec = self.impls_map.inherent_impls .entry(def_id) - .or_insert_with(|| Rc::new(vec![])); + .or_insert_with(|| Arc::new(vec![])); // At this point, there should not be any clones of the - // `Rc`, so we can still safely push into it in place: - Rc::get_mut(&mut rc_vec).unwrap().push(impl_def_id); + // `Arc`, so we can still safely push into it in place: + Arc::get_mut(&mut rc_vec).unwrap().push(impl_def_id); } else { struct_span_err!(self.tcx.sess, item.span, diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs index 418d2b9467096..5498a951bfd70 100644 --- a/src/librustc_typeck/variance/mod.rs +++ b/src/librustc_typeck/variance/mod.rs @@ -17,7 +17,7 @@ use rustc::hir; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::ty::{self, CrateVariancesMap, TyCtxt}; use rustc::ty::maps::Providers; -use std::rc::Rc; +use std::sync::Arc; /// Defines the `TermsContext` basically houses an arena where we can /// allocate terms. @@ -44,16 +44,16 @@ pub fn provide(providers: &mut Providers) { } fn crate_variances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) - -> Rc { + -> Arc { assert_eq!(crate_num, LOCAL_CRATE); let mut arena = arena::TypedArena::new(); let terms_cx = terms::determine_parameters_to_be_inferred(tcx, &mut arena); let constraints_cx = constraints::add_constraints_from_crate(terms_cx); - Rc::new(solve::solve_constraints(constraints_cx)) + Arc::new(solve::solve_constraints(constraints_cx)) } fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId) - -> Rc> { + -> Arc> { let id = tcx.hir.as_local_node_id(item_def_id).expect("expected local def-id"); let unsupported = || { // Variance not relevant. diff --git a/src/librustc_typeck/variance/solve.rs b/src/librustc_typeck/variance/solve.rs index 434e8ce148f3b..5995d00e71466 100644 --- a/src/librustc_typeck/variance/solve.rs +++ b/src/librustc_typeck/variance/solve.rs @@ -18,7 +18,7 @@ use rustc::hir::def_id::DefId; use rustc::ty; use rustc_data_structures::fx::FxHashMap; -use std::rc::Rc; +use std::sync::Arc; use super::constraints::*; use super::terms::*; @@ -51,7 +51,7 @@ pub fn solve_constraints(constraints_cx: ConstraintContext) -> ty::CrateVariance }; solutions_cx.solve(); let variances = solutions_cx.create_map(); - let empty_variance = Rc::new(Vec::new()); + let empty_variance = Arc::new(Vec::new()); ty::CrateVariancesMap { variances, empty_variance } } @@ -88,7 +88,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { } } - fn create_map(&self) -> FxHashMap>> { + fn create_map(&self) -> FxHashMap>> { let tcx = self.terms_cx.tcx; let solutions = &self.solutions; @@ -109,7 +109,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { } } - (def_id, Rc::new(variances)) + (def_id, Arc::new(variances)) }).collect() } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 2ecb7b546fce2..e8713924f53c2 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -15,7 +15,7 @@ use rustc::session::{self, config}; use rustc::hir::def_id::DefId; use rustc::hir::def::Def; use rustc::middle::privacy::AccessLevels; -use rustc::ty::{self, TyCtxt, GlobalArenas}; +use rustc::ty::{self, TyCtxt, AllArenas}; use rustc::hir::map as hir_map; use rustc::lint; use rustc::util::nodemap::FxHashMap; @@ -33,13 +33,13 @@ use errors::emitter::ColorConfig; use std::cell::{RefCell, Cell}; use std::mem; use std::rc::Rc; +use std::sync::Arc; use std::path::PathBuf; use visit_ast::RustdocVisitor; use clean; use clean::Clean; use html::render::RenderInfo; -use arena::DroplessArena; pub use rustc::session::config::Input; pub use rustc::session::search_paths::SearchPaths; @@ -137,7 +137,7 @@ pub fn run_core(search_paths: SearchPaths, ..config::basic_options().clone() }; - let codemap = Rc::new(codemap::CodeMap::new(sessopts.file_path_mapping())); + let codemap = Arc::new(codemap::CodeMap::new(sessopts.file_path_mapping())); let diagnostic_handler = errors::Handler::with_tty_emitter(ColorConfig::Auto, true, false, @@ -173,8 +173,7 @@ pub fn run_core(search_paths: SearchPaths, abort_on_err(result, &sess) }; - let arena = DroplessArena::new(); - let arenas = GlobalArenas::new(); + let arenas = AllArenas::new(); let hir_map = hir_map::map_crate(&sess, &*cstore, &mut hir_forest, &defs); let output_filenames = driver::build_output_filenames(&input, &None, @@ -187,7 +186,6 @@ pub fn run_core(search_paths: SearchPaths, hir_map, analysis, resolutions, - &arena, &arenas, &name, &output_filenames, diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 9bbd16355be38..40ebeebac4b40 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -79,7 +79,7 @@ pub fn run(input: &str, ..config::basic_options().clone() }; - let codemap = Rc::new(CodeMap::new(sessopts.file_path_mapping())); + let codemap = Arc::new(CodeMap::new(sessopts.file_path_mapping())); let handler = errors::Handler::with_tty_emitter(ColorConfig::Auto, true, false, Some(codemap.clone())); @@ -236,7 +236,7 @@ fn run_test(test: &str, cratename: &str, filename: &str, cfgs: Vec, libs } } let data = Arc::new(Mutex::new(Vec::new())); - let codemap = Rc::new(CodeMap::new(sessopts.file_path_mapping())); + let codemap = Arc::new(CodeMap::new(sessopts.file_path_mapping())); let emitter = errors::emitter::EmitterWriter::new(box Sink(data.clone()), Some(codemap.clone()), false); @@ -451,7 +451,7 @@ pub struct Collector { opts: TestOptions, maybe_sysroot: Option, position: Span, - codemap: Option>, + codemap: Option>, filename: Option, // to be removed when hoedown will be removed as well pub render_type: RenderType, @@ -461,7 +461,7 @@ pub struct Collector { impl Collector { pub fn new(cratename: String, cfgs: Vec, libs: SearchPaths, externs: Externs, use_headers: bool, opts: TestOptions, maybe_sysroot: Option, - codemap: Option>, filename: Option, + codemap: Option>, filename: Option, render_type: RenderType, linker: Option) -> Collector { Collector { tests: Vec::new(), diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 3464db2a81111..dd9287c1a92e7 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -24,10 +24,10 @@ pub use self::ExpnFormat::*; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::StableHasher; -use std::cell::{RefCell, Ref}; +use rustc_data_structures::lock::{Lock, LockGuard}; use std::hash::Hash; use std::path::{Path, PathBuf}; -use std::rc::Rc; +use std::sync::Arc; use std::env; use std::fs; @@ -125,32 +125,32 @@ impl StableFilemapId { // pub struct CodeMap { - pub(super) files: RefCell>>, - file_loader: Box, + pub(super) files: Lock>>, + file_loader: Box, // This is used to apply the file path remapping as specified via // -Zremap-path-prefix to all FileMaps allocated within this CodeMap. path_mapping: FilePathMapping, - stable_id_to_filemap: RefCell>>, + stable_id_to_filemap: Lock>>, } impl CodeMap { pub fn new(path_mapping: FilePathMapping) -> CodeMap { CodeMap { - files: RefCell::new(Vec::new()), + files: Lock::new(Vec::new()), file_loader: Box::new(RealFileLoader), path_mapping, - stable_id_to_filemap: RefCell::new(FxHashMap()), + stable_id_to_filemap: Lock::new(FxHashMap()), } } - pub fn with_file_loader(file_loader: Box, + pub fn with_file_loader(file_loader: Box, path_mapping: FilePathMapping) -> CodeMap { CodeMap { - files: RefCell::new(Vec::new()), - file_loader, + files: Lock::new(Vec::new()), + file_loader: file_loader, path_mapping, - stable_id_to_filemap: RefCell::new(FxHashMap()), + stable_id_to_filemap: Lock::new(FxHashMap()), } } @@ -162,16 +162,16 @@ impl CodeMap { self.file_loader.file_exists(path) } - pub fn load_file(&self, path: &Path) -> io::Result> { + pub fn load_file(&self, path: &Path) -> io::Result> { let src = self.file_loader.read_file(path)?; Ok(self.new_filemap(path.to_str().unwrap().to_string(), src)) } - pub fn files(&self) -> Ref>> { + pub fn files(&self) -> LockGuard>> { self.files.borrow() } - pub fn filemap_by_stable_id(&self, stable_id: StableFilemapId) -> Option> { + pub fn filemap_by_stable_id(&self, stable_id: StableFilemapId) -> Option> { self.stable_id_to_filemap.borrow().get(&stable_id).map(|fm| fm.clone()) } @@ -187,7 +187,7 @@ impl CodeMap { /// Creates a new filemap without setting its line information. If you don't /// intend to set the line information yourself, you should use new_filemap_and_lines. - pub fn new_filemap(&self, filename: FileName, src: String) -> Rc { + pub fn new_filemap(&self, filename: FileName, src: String) -> Arc { let start_pos = self.next_start_pos(); let mut files = self.files.borrow_mut(); @@ -199,7 +199,7 @@ impl CodeMap { let unmapped_path = PathBuf::from(filename.clone()); let (filename, was_remapped) = self.path_mapping.map_prefix(filename); - let filemap = Rc::new(FileMap::new( + let filemap = Arc::new(FileMap::new( filename, was_remapped, unmapped_path, @@ -217,7 +217,7 @@ impl CodeMap { } /// Creates a new filemap and sets its line information. - pub fn new_filemap_and_lines(&self, filename: &str, src: &str) -> Rc { + pub fn new_filemap_and_lines(&self, filename: &str, src: &str) -> Arc { let fm = self.new_filemap(filename.to_string(), src.to_owned()); let mut byte_pos: u32 = fm.start_pos.0; for line in src.lines() { @@ -244,7 +244,7 @@ impl CodeMap { mut file_local_lines: Vec, mut file_local_multibyte_chars: Vec, mut file_local_non_narrow_chars: Vec) - -> Rc { + -> Arc { let start_pos = self.next_start_pos(); let mut files = self.files.borrow_mut(); @@ -263,19 +263,19 @@ impl CodeMap { *swc = *swc + start_pos; } - let filemap = Rc::new(FileMap { + let filemap = Arc::new(FileMap { name: filename, name_was_remapped, unmapped_path: None, crate_of_origin, src: None, src_hash, - external_src: RefCell::new(ExternalSource::AbsentOk), + external_src: Lock::new(ExternalSource::AbsentOk), start_pos, end_pos, - lines: RefCell::new(file_local_lines), - multibyte_chars: RefCell::new(file_local_multibyte_chars), - non_narrow_chars: RefCell::new(file_local_non_narrow_chars), + lines: Lock::new(file_local_lines), + multibyte_chars: Lock::new(file_local_multibyte_chars), + non_narrow_chars: Lock::new(file_local_non_narrow_chars), }); files.push(filemap.clone()); @@ -358,7 +358,7 @@ impl CodeMap { } // If the relevant filemap is empty, we don't return a line number. - fn lookup_line(&self, pos: BytePos) -> Result> { + fn lookup_line(&self, pos: BytePos) -> Result> { let idx = self.lookup_filemap_idx(pos); let files = self.files.borrow(); @@ -561,7 +561,7 @@ impl CodeMap { self.span_until_char(sp, '{') } - pub fn get_filemap(&self, filename: &str) -> Option> { + pub fn get_filemap(&self, filename: &str) -> Option> { for fm in self.files.borrow().iter() { if filename == fm.name { return Some(fm.clone()); @@ -658,7 +658,7 @@ impl CodeMapper for CodeMap { } sp } - fn ensure_filemap_source_present(&self, file_map: Rc) -> bool { + fn ensure_filemap_source_present(&self, file_map: Arc) -> bool { file_map.add_external_src( || self.file_loader.read_file(Path::new(&file_map.name)).ok() ) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 0e05cce35e2df..7a342dc04d317 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -27,6 +27,7 @@ use util::small_vector::SmallVector; use std::collections::HashMap; use std::path::PathBuf; use std::rc::Rc; +use std::sync::Arc; use std::default::Default; use tokenstream::{self, TokenStream}; @@ -602,15 +603,15 @@ pub trait Resolver { fn is_whitelisted_legacy_custom_derive(&self, name: Name) -> bool; fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion, derives: &[Mark]); - fn add_builtin(&mut self, ident: ast::Ident, ext: Rc); + fn add_builtin(&mut self, ident: ast::Ident, ext: Arc); fn resolve_imports(&mut self); // Resolves attribute and derive legacy macros from `#![plugin(..)]`. fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec) -> Option; fn resolve_invoc(&mut self, invoc: &mut Invocation, scope: Mark, force: bool) - -> Result>, Determinacy>; + -> Result>, Determinacy>; fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool) - -> Result, Determinacy>; + -> Result, Determinacy>; fn check_unused_macros(&self); } @@ -629,16 +630,16 @@ impl Resolver for DummyResolver { fn is_whitelisted_legacy_custom_derive(&self, _name: Name) -> bool { false } fn visit_expansion(&mut self, _invoc: Mark, _expansion: &Expansion, _derives: &[Mark]) {} - fn add_builtin(&mut self, _ident: ast::Ident, _ext: Rc) {} + fn add_builtin(&mut self, _ident: ast::Ident, _ext: Arc) {} fn resolve_imports(&mut self) {} fn find_legacy_attr_invoc(&mut self, _attrs: &mut Vec) -> Option { None } fn resolve_invoc(&mut self, _invoc: &mut Invocation, _scope: Mark, _force: bool) - -> Result>, Determinacy> { + -> Result>, Determinacy> { Err(Determinacy::Determined) } fn resolve_macro(&mut self, _scope: Mark, _path: &ast::Path, _kind: MacroKind, - _force: bool) -> Result, Determinacy> { + _force: bool) -> Result, Determinacy> { Err(Determinacy::Determined) } fn check_unused_macros(&self) {} diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 614c4a10e6d80..e0f842385a908 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -36,6 +36,7 @@ use visit::Visitor; use std::collections::HashMap; use std::mem; use std::rc::Rc; +use std::sync::Arc; macro_rules! expansions { ($($kind:ident: $ty:ty [$($vec:ident, $ty_elt:ty)*], $kind_name:expr, .$make:ident, @@ -420,7 +421,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } - fn expand_invoc(&mut self, invoc: Invocation, ext: Rc) -> Expansion { + fn expand_invoc(&mut self, invoc: Invocation, ext: Arc) -> Expansion { let result = match invoc.kind { InvocationKind::Bang { .. } => self.expand_bang_invoc(invoc, ext), InvocationKind::Attr { .. } => self.expand_attr_invoc(invoc, ext), @@ -444,7 +445,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { result } - fn expand_attr_invoc(&mut self, invoc: Invocation, ext: Rc) -> Expansion { + fn expand_attr_invoc(&mut self, invoc: Invocation, ext: Arc) -> Expansion { let Invocation { expansion_kind: kind, .. } = invoc; let (attr, item) = match invoc.kind { InvocationKind::Attr { attr, item, .. } => (attr.unwrap(), item), @@ -499,7 +500,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } /// Expand a macro invocation. Returns the result of expansion. - fn expand_bang_invoc(&mut self, invoc: Invocation, ext: Rc) -> Expansion { + fn expand_bang_invoc(&mut self, invoc: Invocation, ext: Arc) -> Expansion { let (mark, kind) = (invoc.expansion_data.mark, invoc.expansion_kind); let (mac, ident, span) = match invoc.kind { InvocationKind::Bang { mac, ident, span } => (mac, ident, span), @@ -625,7 +626,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } /// Expand a derive invocation. Returns the result of expansion. - fn expand_derive_invoc(&mut self, invoc: Invocation, ext: Rc) -> Expansion { + fn expand_derive_invoc(&mut self, invoc: Invocation, ext: Arc) -> Expansion { let Invocation { expansion_kind: kind, .. } = invoc; let (path, item) = match invoc.kind { InvocationKind::Derive { path, item } => (path, item), diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 5e58f003c2be7..5c70394b6db34 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use rustc_data_structures::lock::RwLock; + use {ast, attr}; use syntax_pos::{Span, DUMMY_SP}; use ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension}; @@ -26,7 +28,6 @@ use parse::token::Token::*; use symbol::Symbol; use tokenstream::{TokenStream, TokenTree}; -use std::cell::RefCell; use std::collections::HashMap; use std::collections::hash_map::Entry; use std::rc::Rc; @@ -183,7 +184,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, // Holy self-referential! /// Converts a `macro_rules!` invocation into a syntax extension. -pub fn compile(sess: &ParseSess, features: &RefCell, def: &ast::Item) -> SyntaxExtension { +pub fn compile(sess: &ParseSess, features: &RwLock, def: &ast::Item) -> SyntaxExtension { let lhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("lhs")); let rhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("rhs")); @@ -293,7 +294,7 @@ pub fn compile(sess: &ParseSess, features: &RefCell, def: &ast::Item) } fn check_lhs_nt_follows(sess: &ParseSess, - features: &RefCell, + features: &RwLock, attrs: &[ast::Attribute], lhs: "ed::TokenTree) -> bool { // lhs is going to be like TokenTree::Delimited(...), where the @@ -350,7 +351,7 @@ fn check_rhs(sess: &ParseSess, rhs: "ed::TokenTree) -> bool { } fn check_matcher(sess: &ParseSess, - features: &RefCell, + features: &RwLock, attrs: &[ast::Attribute], matcher: &[quoted::TokenTree]) -> bool { let first_sets = FirstSets::new(matcher); @@ -598,7 +599,7 @@ impl TokenSet { // Requires that `first_sets` is pre-computed for `matcher`; // see `FirstSets::new`. fn check_matcher_core(sess: &ParseSess, - features: &RefCell, + features: &RwLock, attrs: &[ast::Attribute], first_sets: &FirstSets, matcher: &[quoted::TokenTree], @@ -865,7 +866,7 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> Result, + features: &RwLock, attrs: &[ast::Attribute], tok: "ed::TokenTree) -> Result<(), String> { debug!("has_legal_fragment_specifier({:?})", tok); @@ -880,7 +881,7 @@ fn has_legal_fragment_specifier(sess: &ParseSess, } fn is_legal_fragment_specifier(sess: &ParseSess, - features: &RefCell, + features: &RwLock, attrs: &[ast::Attribute], frag_name: &str, frag_span: Span) -> bool { diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs index 6564046ffe68f..4edd83e24c105 100644 --- a/src/libsyntax/json.rs +++ b/src/libsyntax/json.rs @@ -26,7 +26,7 @@ use errors::{DiagnosticBuilder, SubDiagnostic, RenderSpan, CodeSuggestion, CodeM use errors::DiagnosticId; use errors::emitter::Emitter; -use std::rc::Rc; +use std::sync::Arc; use std::io::{self, Write}; use std::vec; @@ -35,13 +35,13 @@ use rustc_serialize::json::{as_json, as_pretty_json}; pub struct JsonEmitter { dst: Box, registry: Option, - cm: Rc, + cm: Arc, pretty: bool, } impl JsonEmitter { pub fn stderr(registry: Option, - code_map: Rc, + code_map: Arc, pretty: bool) -> JsonEmitter { JsonEmitter { dst: Box::new(io::stderr()), @@ -53,12 +53,12 @@ impl JsonEmitter { pub fn basic(pretty: bool) -> JsonEmitter { let file_path_mapping = FilePathMapping::empty(); - JsonEmitter::stderr(None, Rc::new(CodeMap::new(file_path_mapping)), pretty) + JsonEmitter::stderr(None, Arc::new(CodeMap::new(file_path_mapping)), pretty) } pub fn new(dst: Box, registry: Option, - code_map: Rc, + code_map: Arc, pretty: bool) -> JsonEmitter { JsonEmitter { dst, diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 951163d35fa0f..438886f8e9671 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -20,7 +20,7 @@ use std_unicode::property::Pattern_White_Space; use std::borrow::Cow; use std::char; use std::mem::replace; -use std::rc::Rc; +use std::sync::Arc; pub mod comments; mod tokentrees; @@ -48,7 +48,7 @@ pub struct StringReader<'a> { pub col: CharPos, /// The current character (which has been read from self.pos) pub ch: Option, - pub filemap: Rc, + pub filemap: Arc, /// If Some, stop reading the source at this position (inclusive). pub terminator: Option, /// Whether to record new-lines and multibyte chars in filemap. @@ -61,7 +61,7 @@ pub struct StringReader<'a> { pub fatal_errs: Vec>, // cache a direct reference to the source text, so that we don't have to // retrieve it via `self.filemap.src.as_ref().unwrap()` all the time. - source_text: Rc, + source_text: Arc, /// Stack of open delimiters and their spans. Used for error message. token: token::Token, span: Span, @@ -145,13 +145,13 @@ impl<'a> StringReader<'a> { impl<'a> StringReader<'a> { /// For comments.rs, which hackily pokes into next_pos and ch - pub fn new_raw(sess: &'a ParseSess, filemap: Rc) -> Self { + pub fn new_raw(sess: &'a ParseSess, filemap: Arc) -> Self { let mut sr = StringReader::new_raw_internal(sess, filemap); sr.bump(); sr } - fn new_raw_internal(sess: &'a ParseSess, filemap: Rc) -> Self { + fn new_raw_internal(sess: &'a ParseSess, filemap: Arc) -> Self { if filemap.src.is_none() { sess.span_diagnostic.bug(&format!("Cannot lex filemap without source: {}", filemap.name)); @@ -180,7 +180,7 @@ impl<'a> StringReader<'a> { } } - pub fn new(sess: &'a ParseSess, filemap: Rc) -> Self { + pub fn new(sess: &'a ParseSess, filemap: Arc) -> Self { let mut sr = StringReader::new_raw(sess, filemap); if sr.advance_token().is_err() { sr.emit_fatal_errors(); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index c679efd41ea46..78f7e55a668e0 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -10,6 +10,7 @@ //! The main parser interface +use rustc_data_structures::lock::Lock; use ast::{self, CrateConfig}; use codemap::{CodeMap, FilePathMapping}; use syntax_pos::{self, Span, FileMap, NO_EXPANSION}; @@ -21,11 +22,11 @@ use str::char_at; use symbol::Symbol; use tokenstream::{TokenStream, TokenTree}; -use std::cell::RefCell; use std::collections::HashSet; use std::iter; use std::path::{Path, PathBuf}; use std::rc::Rc; +use std::sync::Arc; use std::str; pub type PResult<'a, T> = Result>; @@ -46,15 +47,16 @@ pub struct ParseSess { pub span_diagnostic: Handler, pub unstable_features: UnstableFeatures, pub config: CrateConfig, - pub missing_fragment_specifiers: RefCell>, + pub missing_fragment_specifiers: Lock>, /// Used to determine and report recursive mod inclusions - included_mod_stack: RefCell>, - code_map: Rc, + included_mod_stack: Lock>, // Should be a temporary thread local thing + code_map: Arc, } impl ParseSess { pub fn new(file_path_mapping: FilePathMapping) -> Self { - let cm = Rc::new(CodeMap::new(file_path_mapping)); + ::rustc_data_structures::lock::assert_sync::(); + let cm = Arc::new(CodeMap::new(file_path_mapping)); let handler = Handler::with_tty_emitter(ColorConfig::Auto, true, false, @@ -62,13 +64,13 @@ impl ParseSess { ParseSess::with_span_handler(handler, cm) } - pub fn with_span_handler(handler: Handler, code_map: Rc) -> ParseSess { + pub fn with_span_handler(handler: Handler, code_map: Arc) -> ParseSess { ParseSess { span_diagnostic: handler, unstable_features: UnstableFeatures::from_environment(), config: HashSet::new(), - missing_fragment_specifiers: RefCell::new(HashSet::new()), - included_mod_stack: RefCell::new(vec![]), + missing_fragment_specifiers: Lock::new(HashSet::new()), + included_mod_stack: Lock::new(vec![]), code_map, } } @@ -176,7 +178,7 @@ pub fn new_sub_parser_from_file<'a>(sess: &'a ParseSess, } /// Given a filemap and config, return a parser -pub fn filemap_to_parser(sess: & ParseSess, filemap: Rc, ) -> Parser { +pub fn filemap_to_parser(sess: & ParseSess, filemap: Arc) -> Parser { let end_pos = filemap.end_pos; let mut parser = stream_to_parser(sess, filemap_to_stream(sess, filemap, None)); @@ -199,7 +201,7 @@ pub fn new_parser_from_tts(sess: &ParseSess, tts: Vec) -> Parser { /// Given a session and a path and an optional span (for error reporting), /// add the path to the session's codemap and return the new filemap. fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option) - -> Rc { + -> Arc { match sess.codemap().load_file(path) { Ok(filemap) => filemap, Err(e) => { @@ -213,7 +215,7 @@ fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option) } /// Given a filemap, produce a sequence of token-trees -pub fn filemap_to_stream(sess: &ParseSess, filemap: Rc, override_span: Option) +pub fn filemap_to_stream(sess: &ParseSess, filemap: Arc, override_span: Option) -> TokenStream { let mut srdr = lexer::StringReader::new(sess, filemap); srdr.override_span = override_span; diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index ccf3d5502341f..e2c7212e9fda8 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -10,7 +10,7 @@ //! The compiler code necessary to implement the `#[derive]` extensions. -use std::rc::Rc; +use std::sync::Arc; use syntax::ast; use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension, Resolver}; use syntax::ext::build::AstBuilder; @@ -81,7 +81,7 @@ macro_rules! derive_traits { $( resolver.add_builtin( ast::Ident::with_empty_ctxt(Symbol::intern($name)), - Rc::new(SyntaxExtension::BuiltinDerive($func)) + Arc::new(SyntaxExtension::BuiltinDerive($func)) ); )* } diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 42bbb4ae0cbee..63c61fb818334 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -43,7 +43,7 @@ pub mod deriving; pub mod proc_macro_impl; -use std::rc::Rc; +use std::sync::Arc; use syntax::ast; use syntax::ext::base::{MacroExpanderFn, NormalTT, NamedSyntaxExtension}; use syntax::symbol::Symbol; @@ -54,7 +54,7 @@ pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver, deriving::register_builtin_derives(resolver); let mut register = |name, ext| { - resolver.add_builtin(ast::Ident::with_empty_ctxt(name), Rc::new(ext)); + resolver.add_builtin(ast::Ident::with_empty_ctxt(name), Arc::new(ext)); }; macro_rules! register { diff --git a/src/libsyntax_pos/Cargo.toml b/src/libsyntax_pos/Cargo.toml index aad2155157d84..bb4123848d4d2 100644 --- a/src/libsyntax_pos/Cargo.toml +++ b/src/libsyntax_pos/Cargo.toml @@ -12,3 +12,4 @@ crate-type = ["dylib"] serialize = { path = "../libserialize" } rustc_data_structures = { path = "../librustc_data_structures" } unicode-width = "0.1.4" +lazy_static = "0.2.9" \ No newline at end of file diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 47755dc1d5468..dc756001ba461 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -27,15 +27,19 @@ #![feature(specialization)] use std::borrow::Cow; -use std::cell::{Cell, RefCell}; +use std::cell::Cell; use std::cmp::{self, Ordering}; use std::fmt; use std::hash::Hasher; use std::ops::{Add, Sub}; use std::path::PathBuf; -use std::rc::Rc; +use std::sync::Arc; use rustc_data_structures::stable_hasher::StableHasher; +use rustc_data_structures::lock::Lock; + +#[macro_use] +extern crate lazy_static; extern crate rustc_data_structures; @@ -92,10 +96,6 @@ impl SpanData { } } -// The interner in thread-local, so `Span` shouldn't move between threads. -impl !Send for Span {} -impl !Sync for Span {} - impl PartialOrd for Span { fn partial_cmp(&self, rhs: &Self) -> Option { PartialOrd::partial_cmp(&self.data(), &rhs.data()) @@ -597,22 +597,22 @@ pub struct FileMap { /// Indicates which crate this FileMap was imported from. pub crate_of_origin: u32, /// The complete source code - pub src: Option>, + pub src: Option>, /// The source code's hash pub src_hash: u128, /// The external source code (used for external crates, which will have a `None` /// value as `self.src`. - pub external_src: RefCell, + pub external_src: Lock, /// The start position of this source in the CodeMap pub start_pos: BytePos, /// The end position of this source in the CodeMap pub end_pos: BytePos, /// Locations of lines beginnings in the source code - pub lines: RefCell>, + pub lines: Lock>, /// Locations of multi-byte characters in the source code - pub multibyte_chars: RefCell>, + pub multibyte_chars: Lock>, /// Width of characters that are not narrow in the source code - pub non_narrow_chars: RefCell>, + pub non_narrow_chars: Lock>, } impl Encodable for FileMap { @@ -735,10 +735,10 @@ impl Decodable for FileMap { end_pos, src: None, src_hash, - external_src: RefCell::new(ExternalSource::AbsentOk), - lines: RefCell::new(lines), - multibyte_chars: RefCell::new(multibyte_chars), - non_narrow_chars: RefCell::new(non_narrow_chars) + external_src: Lock::new(ExternalSource::AbsentOk), + lines: Lock::new(lines), + multibyte_chars: Lock::new(multibyte_chars), + non_narrow_chars: Lock::new(non_narrow_chars) }) }) } @@ -769,14 +769,14 @@ impl FileMap { name_was_remapped, unmapped_path: Some(unmapped_path), crate_of_origin: 0, - src: Some(Rc::new(src)), + src: Some(Arc::new(src)), src_hash, - external_src: RefCell::new(ExternalSource::Unneeded), + external_src: Lock::new(ExternalSource::Unneeded), start_pos, end_pos: Pos::from_usize(end_pos), - lines: RefCell::new(Vec::new()), - multibyte_chars: RefCell::new(Vec::new()), - non_narrow_chars: RefCell::new(Vec::new()), + lines: Lock::new(Vec::new()), + multibyte_chars: Lock::new(Vec::new()), + non_narrow_chars: Lock::new(Vec::new()), } } @@ -1025,7 +1025,7 @@ impl Sub for CharPos { #[derive(Debug, Clone)] pub struct Loc { /// Information about the original source - pub file: Rc, + pub file: Arc, /// The (1-based) line number pub line: usize, /// The (0-based) column offset @@ -1042,14 +1042,14 @@ pub struct LocWithOpt { pub filename: FileName, pub line: usize, pub col: CharPos, - pub file: Option>, + pub file: Option>, } // used to be structural records. Better names, anyone? #[derive(Debug)] -pub struct FileMapAndLine { pub fm: Rc, pub line: usize } +pub struct FileMapAndLine { pub fm: Arc, pub line: usize } #[derive(Debug)] -pub struct FileMapAndBytePos { pub fm: Rc, pub pos: BytePos } +pub struct FileMapAndBytePos { pub fm: Arc, pub pos: BytePos } #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct LineInfo { @@ -1064,7 +1064,7 @@ pub struct LineInfo { } pub struct FileLines { - pub file: Rc, + pub file: Arc, pub lines: Vec } diff --git a/src/libsyntax_pos/span_encoding.rs b/src/libsyntax_pos/span_encoding.rs index b23e40ce7a932..72e52ac63c7b4 100644 --- a/src/libsyntax_pos/span_encoding.rs +++ b/src/libsyntax_pos/span_encoding.rs @@ -17,8 +17,8 @@ use {BytePos, SpanData}; use hygiene::SyntaxContext; +use rustc_data_structures::lock::Lock; use rustc_data_structures::fx::FxHashMap; -use std::cell::RefCell; /// A compressed span. /// Contains either fields of `SpanData` inline if they are small, or index into span interner. @@ -135,11 +135,11 @@ impl SpanInterner { } } -// If an interner exists in TLS, return it. Otherwise, prepare a fresh one. +// If an interner exists, return it. Otherwise, prepare a fresh one. #[inline] fn with_span_interner T>(f: F) -> T { - thread_local!(static INTERNER: RefCell = { - RefCell::new(SpanInterner::default()) - }); - INTERNER.with(|interner| f(&mut *interner.borrow_mut())) + lazy_static! { + static ref INTERNER: Lock = Lock::new(SpanInterner::default()); + } + f(&mut *INTERNER.borrow_mut()) } diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 69ddd56021377..d7b91fd6f9ef0 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -14,8 +14,8 @@ use hygiene::SyntaxContext; +use rustc_data_structures::lock::Lock; use serialize::{Decodable, Decoder, Encodable, Encoder}; -use std::cell::RefCell; use std::collections::HashMap; use std::fmt; @@ -79,10 +79,6 @@ impl Decodable for Ident { #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Symbol(u32); -// The interner in thread-local, so `Symbol` shouldn't move between threads. -impl !Send for Symbol { } -impl !Sync for Symbol { } - impl Symbol { /// Maps a string to its interned representation. pub fn intern(string: &str) -> Self { @@ -317,12 +313,14 @@ declare_keywords! { (60, Union, "union") } -// If an interner exists in TLS, return it. Otherwise, prepare a fresh one. + +// If an interner exists, return it. Otherwise, prepare a fresh one. +#[inline] fn with_interner T>(f: F) -> T { - thread_local!(static INTERNER: RefCell = { - RefCell::new(Interner::fresh()) - }); - INTERNER.with(|interner| f(&mut *interner.borrow_mut())) + lazy_static! { + static ref INTERNER: Lock = Lock::new(Interner::fresh()); + } + f(&mut *INTERNER.borrow_mut()) } /// Represents a string stored in the thread-local interner. Because the