Skip to content

Commit 3f40227

Browse files
committed
Add support for parsing with rust-analyzer instead of librustc_parse
This adds a new librustc_parse_ra library that implements the same interface of librustc_parse, but uses rust-analyzer to parse the code, and then converts the rust-analyzer AST to the rustc AST, and adds a new -Z parse-with-rust-analyzer option that makes rustc use it, gated by a new rust_analyzer feature flag and config.toml option. The code is preliminary but should be essentially complete, and capable of building large projects that only use the Rust 2018 edition (Rust 2015 is not currently supported by rust-analyzer). Note that this is likely to accept invalid code, is not fully complete, and provides worse error messages than the current parser, so it cannot be stabilized without significant additional work.
1 parent 1b521f5 commit 3f40227

File tree

13 files changed

+3261
-11
lines changed

13 files changed

+3261
-11
lines changed

Cargo.lock

+151-5
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ dependencies = [
740740
"crossbeam-utils 0.6.5",
741741
"lazy_static 1.4.0",
742742
"memoffset",
743-
"scopeguard",
743+
"scopeguard 1.0.0",
744744
]
745745

746746
[[package]]
@@ -952,6 +952,12 @@ dependencies = [
952952
"rustc-std-workspace-core",
953953
]
954954

955+
[[package]]
956+
name = "drop_bomb"
957+
version = "0.1.4"
958+
source = "registry+https://github.com/rust-lang/crates.io-index"
959+
checksum = "69b26e475fd29098530e709294e94e661974c851aed42512793f120fed4e199f"
960+
955961
[[package]]
956962
name = "dtoa"
957963
version = "0.4.4"
@@ -1404,7 +1410,7 @@ version = "0.5.1"
14041410
source = "registry+https://github.com/rust-lang/crates.io-index"
14051411
checksum = "a3753954f7bd71f0e671afb8b5a992d1724cf43b7f95a563cd4a0bde94659ca8"
14061412
dependencies = [
1407-
"scopeguard",
1413+
"scopeguard 1.0.0",
14081414
"winapi 0.3.8",
14091415
]
14101416

@@ -1864,13 +1870,23 @@ version = "0.5.2"
18641870
source = "registry+https://github.com/rust-lang/crates.io-index"
18651871
checksum = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
18661872

1873+
[[package]]
1874+
name = "lock_api"
1875+
version = "0.1.5"
1876+
source = "registry+https://github.com/rust-lang/crates.io-index"
1877+
checksum = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
1878+
dependencies = [
1879+
"owning_ref",
1880+
"scopeguard 0.3.3",
1881+
]
1882+
18671883
[[package]]
18681884
name = "lock_api"
18691885
version = "0.3.1"
18701886
source = "registry+https://github.com/rust-lang/crates.io-index"
18711887
checksum = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc"
18721888
dependencies = [
1873-
"scopeguard",
1889+
"scopeguard 1.0.0",
18741890
]
18751891

18761892
[[package]]
@@ -2345,6 +2361,15 @@ dependencies = [
23452361
"winapi 0.3.8",
23462362
]
23472363

2364+
[[package]]
2365+
name = "owning_ref"
2366+
version = "0.4.1"
2367+
source = "registry+https://github.com/rust-lang/crates.io-index"
2368+
checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce"
2369+
dependencies = [
2370+
"stable_deref_trait",
2371+
]
2372+
23482373
[[package]]
23492374
name = "packed_simd"
23502375
version = "0.3.1"
@@ -2393,13 +2418,33 @@ dependencies = [
23932418
"winapi 0.3.8",
23942419
]
23952420

2421+
[[package]]
2422+
name = "parking_lot"
2423+
version = "0.6.4"
2424+
source = "registry+https://github.com/rust-lang/crates.io-index"
2425+
checksum = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
2426+
dependencies = [
2427+
"lock_api 0.1.5",
2428+
"parking_lot_core 0.3.1",
2429+
]
2430+
2431+
[[package]]
2432+
name = "parking_lot"
2433+
version = "0.7.1"
2434+
source = "registry+https://github.com/rust-lang/crates.io-index"
2435+
checksum = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
2436+
dependencies = [
2437+
"lock_api 0.1.5",
2438+
"parking_lot_core 0.4.0",
2439+
]
2440+
23962441
[[package]]
23972442
name = "parking_lot"
23982443
version = "0.9.0"
23992444
source = "registry+https://github.com/rust-lang/crates.io-index"
24002445
checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
24012446
dependencies = [
2402-
"lock_api",
2447+
"lock_api 0.3.1",
24032448
"parking_lot_core 0.6.2",
24042449
"rustc_version",
24052450
]
@@ -2410,10 +2455,36 @@ version = "0.10.0"
24102455
source = "registry+https://github.com/rust-lang/crates.io-index"
24112456
checksum = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc"
24122457
dependencies = [
2413-
"lock_api",
2458+
"lock_api 0.3.1",
24142459
"parking_lot_core 0.7.0",
24152460
]
24162461

2462+
[[package]]
2463+
name = "parking_lot_core"
2464+
version = "0.3.1"
2465+
source = "registry+https://github.com/rust-lang/crates.io-index"
2466+
checksum = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c"
2467+
dependencies = [
2468+
"libc",
2469+
"rand 0.5.6",
2470+
"rustc_version",
2471+
"smallvec 0.6.10",
2472+
"winapi 0.3.8",
2473+
]
2474+
2475+
[[package]]
2476+
name = "parking_lot_core"
2477+
version = "0.4.0"
2478+
source = "registry+https://github.com/rust-lang/crates.io-index"
2479+
checksum = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
2480+
dependencies = [
2481+
"libc",
2482+
"rand 0.6.1",
2483+
"rustc_version",
2484+
"smallvec 0.6.10",
2485+
"winapi 0.3.8",
2486+
]
2487+
24172488
[[package]]
24182489
name = "parking_lot_core"
24192490
version = "0.6.2"
@@ -2713,6 +2784,20 @@ dependencies = [
27132784
"proc-macro2 1.0.3",
27142785
]
27152786

2787+
[[package]]
2788+
name = "ra_syntax"
2789+
version = "0.1.0"
2790+
source = "registry+https://github.com/rust-lang/crates.io-index"
2791+
checksum = "be308e1907623f15bc874a4b2742b6a20c44c439f201638fa26564e664276ce9"
2792+
dependencies = [
2793+
"drop_bomb",
2794+
"itertools 0.7.8",
2795+
"parking_lot 0.6.4",
2796+
"rowan",
2797+
"text_unit",
2798+
"unicode-xid 0.1.0",
2799+
]
2800+
27162801
[[package]]
27172802
name = "racer"
27182803
version = "2.1.31"
@@ -2736,6 +2821,19 @@ dependencies = [
27362821
"rustc-ap-syntax",
27372822
]
27382823

2824+
[[package]]
2825+
name = "rand"
2826+
version = "0.5.6"
2827+
source = "registry+https://github.com/rust-lang/crates.io-index"
2828+
checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
2829+
dependencies = [
2830+
"cloudabi",
2831+
"fuchsia-cprng",
2832+
"libc",
2833+
"rand_core 0.3.0",
2834+
"winapi 0.3.8",
2835+
]
2836+
27392837
[[package]]
27402838
name = "rand"
27412839
version = "0.6.1"
@@ -3141,6 +3239,17 @@ dependencies = [
31413239
"rls-span",
31423240
]
31433241

3242+
[[package]]
3243+
name = "rowan"
3244+
version = "0.1.4"
3245+
source = "registry+https://github.com/rust-lang/crates.io-index"
3246+
checksum = "c218b4430ab922850b71b14fa9bca224425097f935f6155c0b6a4b1f398a54f0"
3247+
dependencies = [
3248+
"parking_lot 0.7.1",
3249+
"smol_str",
3250+
"text_unit",
3251+
]
3252+
31443253
[[package]]
31453254
name = "rustbook"
31463255
version = "0.1.0"
@@ -3849,6 +3958,7 @@ dependencies = [
38493958
"rustc_mir",
38503959
"rustc_mir_build",
38513960
"rustc_parse",
3961+
"rustc_parse_ra",
38523962
"rustc_passes",
38533963
"rustc_plugin_impl",
38543964
"rustc_privacy",
@@ -4045,6 +4155,24 @@ dependencies = [
40454155
"unicode-normalization",
40464156
]
40474157

4158+
[[package]]
4159+
name = "rustc_parse_ra"
4160+
version = "0.0.0"
4161+
dependencies = [
4162+
"bitflags",
4163+
"log",
4164+
"ra_syntax",
4165+
"rustc_ast",
4166+
"rustc_ast_pretty",
4167+
"rustc_data_structures",
4168+
"rustc_errors",
4169+
"rustc_parse",
4170+
"rustc_session",
4171+
"rustc_span",
4172+
"smallvec 1.0.0",
4173+
"unicode-normalization",
4174+
]
4175+
40484176
[[package]]
40494177
name = "rustc_passes"
40504178
version = "0.0.0"
@@ -4443,6 +4571,12 @@ version = "0.1.9"
44434571
source = "registry+https://github.com/rust-lang/crates.io-index"
44444572
checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
44454573

4574+
[[package]]
4575+
name = "scopeguard"
4576+
version = "0.3.3"
4577+
source = "registry+https://github.com/rust-lang/crates.io-index"
4578+
checksum = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
4579+
44464580
[[package]]
44474581
name = "scopeguard"
44484582
version = "1.0.0"
@@ -4625,6 +4759,12 @@ version = "1.0.0"
46254759
source = "registry+https://github.com/rust-lang/crates.io-index"
46264760
checksum = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
46274761

4762+
[[package]]
4763+
name = "smol_str"
4764+
version = "0.1.15"
4765+
source = "registry+https://github.com/rust-lang/crates.io-index"
4766+
checksum = "34836c9a295c62c2ce3514471117c5cb269891e8421b2aafdd910050576c4d8b"
4767+
46284768
[[package]]
46294769
name = "socket2"
46304770
version = "0.3.11"
@@ -4921,6 +5061,12 @@ dependencies = [
49215061
"term 0.6.0",
49225062
]
49235063

5064+
[[package]]
5065+
name = "text_unit"
5066+
version = "0.1.10"
5067+
source = "registry+https://github.com/rust-lang/crates.io-index"
5068+
checksum = "20431e104bfecc1a40872578dbc390e10290a0e9c35fffe3ce6f73c15a9dbfc2"
5069+
49245070
[[package]]
49255071
name = "textwrap"
49265072
version = "0.11.0"

config.toml.example

+3
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,9 @@
436436
# override the default allocator for rustc and LLVM.
437437
#jemalloc = false
438438

439+
# Enable experimental features that depend on rust-analyzer.
440+
#rust-analyzer = false
441+
439442
# Run tests in various test suites with the "nll compare mode" in addition to
440443
# running the tests in normal mode. Largely only used on CI and during local
441444
# development of NLL

src/bootstrap/config.rs

+3
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ pub struct Config {
117117
pub targets: Vec<Interned<String>>,
118118
pub local_rebuild: bool,
119119
pub jemalloc: bool,
120+
pub rust_analyzer: bool,
120121
pub control_flow_guard: bool,
121122

122123
// dist misc
@@ -342,6 +343,7 @@ struct Rust {
342343
thin_lto_import_instr_limit: Option<u32>,
343344
remap_debuginfo: Option<bool>,
344345
jemalloc: Option<bool>,
346+
rust_analyzer: Option<bool>,
345347
test_compare_mode: Option<bool>,
346348
llvm_libunwind: Option<bool>,
347349
control_flow_guard: Option<bool>,
@@ -571,6 +573,7 @@ impl Config {
571573
set(&mut config.codegen_tests, rust.codegen_tests);
572574
set(&mut config.rust_rpath, rust.rpath);
573575
set(&mut config.jemalloc, rust.jemalloc);
576+
set(&mut config.rust_analyzer, rust.rust_analyzer);
574577
set(&mut config.test_compare_mode, rust.test_compare_mode);
575578
set(&mut config.llvm_libunwind, rust.llvm_libunwind);
576579
set(&mut config.backtrace, rust.backtrace);

src/bootstrap/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,9 @@ impl Build {
509509
if self.config.jemalloc {
510510
features.push_str("jemalloc");
511511
}
512+
if self.config.rust_analyzer {
513+
features.push_str("rust_analyzer");
514+
}
512515
if self.config.llvm_enabled() {
513516
features.push_str(" llvm");
514517
}

src/librustc_driver/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"]
4040

4141
[features]
4242
llvm = ['rustc_interface/llvm']
43+
rust_analyzer = ['rustc_interface/rust_analyzer']

src/librustc_interface/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ rustc_attr = { path = "../librustc_attr" }
1818
rustc_builtin_macros = { path = "../librustc_builtin_macros" }
1919
rustc_expand = { path = "../librustc_expand" }
2020
rustc_parse = { path = "../librustc_parse" }
21+
rustc_parse_ra = { path = "../librustc_parse_ra", optional = true }
2122
rustc_session = { path = "../librustc_session" }
2223
rustc_span = { path = "../librustc_span" }
2324
rustc_serialize = { path = "../libserialize", package = "serialize" }
@@ -55,3 +56,4 @@ rustc_target = { path = "../librustc_target" }
5556

5657
[features]
5758
llvm = ['rustc_codegen_llvm']
59+
rust_analyzer = ['rustc_parse_ra']

src/librustc_interface/passes.rs

+32-5
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,40 @@ use std::path::PathBuf;
5050
use std::rc::Rc;
5151
use std::{env, fs, iter, mem};
5252

53-
pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
54-
let krate = sess.time("parse_crate", || match input {
55-
Input::File(file) => parse_crate_from_file(file, &sess.parse_sess),
53+
#[cfg(rust_analyzer)]
54+
fn parse_with_ra<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate>
55+
{
56+
match input {
57+
Input::File(file) => {
58+
rustc_parse_ra::parse_crate_from_file(file, &sess.parse_sess)
59+
},
5660
Input::Str { input, name } => {
57-
parse_crate_from_source_str(name.clone(), input.clone(), &sess.parse_sess)
61+
rustc_parse_ra::parse_crate_from_source_str(name.clone(), input.clone(), &sess.parse_sess)
5862
}
59-
})?;
63+
}
64+
}
65+
66+
#[cfg(not(rust_analyzer))]
67+
fn parse_with_ra<'a>(sess: &'a Session, _input: &Input) -> PResult<'a, ast::Crate>
68+
{
69+
Err(sess.struct_fatal("parsing with rust-analyzer is not supported because this version of rustc was not compiled with the \"rust_analyzer\" feature flag enabled"))
70+
}
71+
72+
pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
73+
let krate = sess.time("parse_crate", ||
74+
if sess.opts.debugging_opts.parse_with_rust_analyzer {
75+
parse_with_ra(sess, input)
76+
} else {
77+
match input {
78+
Input::File(file) => {
79+
parse_crate_from_file(file, &sess.parse_sess)
80+
},
81+
Input::Str { input, name } => {
82+
parse_crate_from_source_str(name.clone(), input.clone(), &sess.parse_sess)
83+
}
84+
}
85+
}
86+
)?;
6087

6188
if sess.opts.debugging_opts.ast_json_noexpand {
6289
println!("{}", json::as_json(&krate));

src/librustc_parse/lexer/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ impl<'a> StringReader<'a> {
8383
let mut sr = StringReader::new(sess, begin.sf, None);
8484

8585
// Seek the lexer to the right byte range.
86+
sr.pos = span.lo();
8687
sr.end_src_index = sr.src_index(span.hi());
8788

8889
sr

0 commit comments

Comments
 (0)