diff options
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/lib.rs | 22 | ||||
-rw-r--r-- | crates/ra_ide/src/goto_type_definition.rs | 22 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/params.rs | 5 | ||||
-rw-r--r-- | crates/ra_project_model/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ra_project_model/src/cargo_workspace.rs | 11 | ||||
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 51 | ||||
-rw-r--r-- | crates/ra_project_model/src/sysroot.rs | 14 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rs | 1 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.txt | 26 |
11 files changed, 117 insertions, 40 deletions
diff --git a/Cargo.lock b/Cargo.lock index 45804c087..f1651edaa 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -1247,6 +1247,7 @@ dependencies = [ | |||
1247 | name = "ra_project_model" | 1247 | name = "ra_project_model" |
1248 | version = "0.1.0" | 1248 | version = "0.1.0" |
1249 | dependencies = [ | 1249 | dependencies = [ |
1250 | "anyhow", | ||
1250 | "cargo_metadata", | 1251 | "cargo_metadata", |
1251 | "log", | 1252 | "log", |
1252 | "ra_arena", | 1253 | "ra_arena", |
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index 7cf3b59a7..9506f2e1c 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs | |||
@@ -323,11 +323,18 @@ impl<T: Clone> InFile<&T> { | |||
323 | } | 323 | } |
324 | } | 324 | } |
325 | 325 | ||
326 | impl<T> InFile<Option<T>> { | ||
327 | pub fn transpose(self) -> Option<InFile<T>> { | ||
328 | let value = self.value?; | ||
329 | Some(InFile::new(self.file_id, value)) | ||
330 | } | ||
331 | } | ||
332 | |||
326 | impl InFile<SyntaxNode> { | 333 | impl InFile<SyntaxNode> { |
327 | pub fn ancestors_with_macros<'a>( | 334 | pub fn ancestors_with_macros( |
328 | self, | 335 | self, |
329 | db: &'a impl crate::db::AstDatabase, | 336 | db: &impl crate::db::AstDatabase, |
330 | ) -> impl Iterator<Item = InFile<SyntaxNode>> + 'a { | 337 | ) -> impl Iterator<Item = InFile<SyntaxNode>> + '_ { |
331 | std::iter::successors(Some(self), move |node| match node.value.parent() { | 338 | std::iter::successors(Some(self), move |node| match node.value.parent() { |
332 | Some(parent) => Some(node.with_value(parent)), | 339 | Some(parent) => Some(node.with_value(parent)), |
333 | None => { | 340 | None => { |
@@ -338,6 +345,15 @@ impl InFile<SyntaxNode> { | |||
338 | } | 345 | } |
339 | } | 346 | } |
340 | 347 | ||
348 | impl InFile<SyntaxToken> { | ||
349 | pub fn ancestors_with_macros( | ||
350 | self, | ||
351 | db: &impl crate::db::AstDatabase, | ||
352 | ) -> impl Iterator<Item = InFile<SyntaxNode>> + '_ { | ||
353 | self.map(|it| it.parent()).ancestors_with_macros(db) | ||
354 | } | ||
355 | } | ||
356 | |||
341 | impl<N: AstNode> InFile<N> { | 357 | impl<N: AstNode> InFile<N> { |
342 | pub fn descendants<T: AstNode>(self) -> impl Iterator<Item = InFile<T>> { | 358 | pub fn descendants<T: AstNode>(self) -> impl Iterator<Item = InFile<T>> { |
343 | self.value.syntax().descendants().filter_map(T::cast).map(move |n| self.with_value(n)) | 359 | self.value.syntax().descendants().filter_map(T::cast).map(move |n| self.with_value(n)) |
diff --git a/crates/ra_ide/src/goto_type_definition.rs b/crates/ra_ide/src/goto_type_definition.rs index 11ad6d137..69940fc36 100644 --- a/crates/ra_ide/src/goto_type_definition.rs +++ b/crates/ra_ide/src/goto_type_definition.rs | |||
@@ -16,24 +16,16 @@ pub(crate) fn goto_type_definition( | |||
16 | let token = pick_best(file.token_at_offset(position.offset))?; | 16 | let token = pick_best(file.token_at_offset(position.offset))?; |
17 | let token = descend_into_macros(db, position.file_id, token); | 17 | let token = descend_into_macros(db, position.file_id, token); |
18 | 18 | ||
19 | let node = token.value.ancestors().find_map(|token| { | 19 | let node = token |
20 | token | 20 | .value |
21 | .ancestors() | 21 | .ancestors() |
22 | .find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some()) | 22 | .find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some())?; |
23 | })?; | ||
24 | 23 | ||
25 | let analyzer = hir::SourceAnalyzer::new(db, token.with_value(&node), None); | 24 | let analyzer = hir::SourceAnalyzer::new(db, token.with_value(&node), None); |
26 | 25 | ||
27 | let ty: hir::Type = if let Some(ty) = | 26 | let ty: hir::Type = ast::Expr::cast(node.clone()) |
28 | ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e)) | 27 | .and_then(|e| analyzer.type_of(db, &e)) |
29 | { | 28 | .or_else(|| ast::Pat::cast(node.clone()).and_then(|p| analyzer.type_of_pat(db, &p)))?; |
30 | ty | ||
31 | } else if let Some(ty) = ast::Pat::cast(node.clone()).and_then(|p| analyzer.type_of_pat(db, &p)) | ||
32 | { | ||
33 | ty | ||
34 | } else { | ||
35 | return None; | ||
36 | }; | ||
37 | 29 | ||
38 | let adt_def = ty.autoderef(db).find_map(|ty| ty.as_adt())?; | 30 | let adt_def = ty.autoderef(db).find_map(|ty| ty.as_adt())?; |
39 | 31 | ||
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 59c86bbfa..2e598fdcd 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -758,7 +758,7 @@ pub fn handle_code_lens( | |||
758 | // Gather runnables | 758 | // Gather runnables |
759 | for runnable in world.analysis().runnables(file_id)? { | 759 | for runnable in world.analysis().runnables(file_id)? { |
760 | let title = match &runnable.kind { | 760 | let title = match &runnable.kind { |
761 | RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => "▶️Run Test", | 761 | RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => "▶️\u{fe0e}Run Test", |
762 | RunnableKind::Bench { .. } => "Run Bench", | 762 | RunnableKind::Bench { .. } => "Run Bench", |
763 | RunnableKind::Bin => "Run", | 763 | RunnableKind::Bin => "Run", |
764 | } | 764 | } |
diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs index ed4f93347..272661b1d 100644 --- a/crates/ra_parser/src/grammar/params.rs +++ b/crates/ra_parser/src/grammar/params.rs | |||
@@ -114,8 +114,11 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) { | |||
114 | // test fn_pointer_param_ident_path | 114 | // test fn_pointer_param_ident_path |
115 | // type Foo = fn(Bar::Baz); | 115 | // type Foo = fn(Bar::Baz); |
116 | // type Qux = fn(baz: Bar::Baz); | 116 | // type Qux = fn(baz: Bar::Baz); |
117 | |||
118 | // test fn_pointer_unnamed_arg | ||
119 | // type Foo = fn(_: bar); | ||
117 | Flavor::FnPointer => { | 120 | Flavor::FnPointer => { |
118 | if p.at(IDENT) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) { | 121 | if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) { |
119 | patterns::pattern_single(p); | 122 | patterns::pattern_single(p); |
120 | types::ascription(p); | 123 | types::ascription(p); |
121 | } else { | 124 | } else { |
diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml index 69edc3c66..653d5bd14 100644 --- a/crates/ra_project_model/Cargo.toml +++ b/crates/ra_project_model/Cargo.toml | |||
@@ -19,3 +19,5 @@ ra_cfg = { path = "../ra_cfg" } | |||
19 | 19 | ||
20 | serde = { version = "1.0.89", features = ["derive"] } | 20 | serde = { version = "1.0.89", features = ["derive"] } |
21 | serde_json = "1.0.39" | 21 | serde_json = "1.0.39" |
22 | |||
23 | anyhow = "1.0.26" | ||
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index 60cb8c1eb..22d226a74 100644 --- a/crates/ra_project_model/src/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs | |||
@@ -2,14 +2,13 @@ | |||
2 | 2 | ||
3 | use std::path::{Path, PathBuf}; | 3 | use std::path::{Path, PathBuf}; |
4 | 4 | ||
5 | use anyhow::{Context, Result}; | ||
5 | use cargo_metadata::{CargoOpt, MetadataCommand}; | 6 | use cargo_metadata::{CargoOpt, MetadataCommand}; |
6 | use ra_arena::{impl_arena_id, Arena, RawId}; | 7 | use ra_arena::{impl_arena_id, Arena, RawId}; |
7 | use ra_db::Edition; | 8 | use ra_db::Edition; |
8 | use rustc_hash::FxHashMap; | 9 | use rustc_hash::FxHashMap; |
9 | use serde::Deserialize; | 10 | use serde::Deserialize; |
10 | 11 | ||
11 | use crate::Result; | ||
12 | |||
13 | /// `CargoWorkspace` represents the logical structure of, well, a Cargo | 12 | /// `CargoWorkspace` represents the logical structure of, well, a Cargo |
14 | /// workspace. It pretty closely mirrors `cargo metadata` output. | 13 | /// workspace. It pretty closely mirrors `cargo metadata` output. |
15 | /// | 14 | /// |
@@ -171,7 +170,9 @@ impl CargoWorkspace { | |||
171 | if let Some(parent) = cargo_toml.parent() { | 170 | if let Some(parent) = cargo_toml.parent() { |
172 | meta.current_dir(parent); | 171 | meta.current_dir(parent); |
173 | } | 172 | } |
174 | let meta = meta.exec().map_err(|e| format!("cargo metadata failed: {}", e))?; | 173 | let meta = meta.exec().with_context(|| { |
174 | format!("Failed to run `cargo metadata --manifest-path {}`", cargo_toml.display()) | ||
175 | })?; | ||
175 | let mut pkg_by_id = FxHashMap::default(); | 176 | let mut pkg_by_id = FxHashMap::default(); |
176 | let mut packages = Arena::default(); | 177 | let mut packages = Arena::default(); |
177 | let mut targets = Arena::default(); | 178 | let mut targets = Arena::default(); |
@@ -181,7 +182,9 @@ impl CargoWorkspace { | |||
181 | for meta_pkg in meta.packages { | 182 | for meta_pkg in meta.packages { |
182 | let cargo_metadata::Package { id, edition, name, manifest_path, .. } = meta_pkg; | 183 | let cargo_metadata::Package { id, edition, name, manifest_path, .. } = meta_pkg; |
183 | let is_member = ws_members.contains(&id); | 184 | let is_member = ws_members.contains(&id); |
184 | let edition = edition.parse::<Edition>()?; | 185 | let edition = edition |
186 | .parse::<Edition>() | ||
187 | .with_context(|| format!("Failed to parse edition {}", edition))?; | ||
185 | let pkg = packages.alloc(PackageData { | 188 | let pkg = packages.alloc(PackageData { |
186 | name, | 189 | name, |
187 | manifest: manifest_path, | 190 | manifest: manifest_path, |
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index bc1d15406..fef405b7f 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -12,6 +12,7 @@ use std::{ | |||
12 | process::Command, | 12 | process::Command, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | use anyhow::{bail, Context, Result}; | ||
15 | use ra_cfg::CfgOptions; | 16 | use ra_cfg::CfgOptions; |
16 | use ra_db::{CrateGraph, CrateId, CrateName, Edition, Env, FileId}; | 17 | use ra_db::{CrateGraph, CrateId, CrateName, Edition, Env, FileId}; |
17 | use rustc_hash::FxHashMap; | 18 | use rustc_hash::FxHashMap; |
@@ -23,8 +24,6 @@ pub use crate::{ | |||
23 | sysroot::Sysroot, | 24 | sysroot::Sysroot, |
24 | }; | 25 | }; |
25 | 26 | ||
26 | pub type Result<T> = ::std::result::Result<T, Box<dyn Error + Send + Sync>>; | ||
27 | |||
28 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | 27 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] |
29 | pub struct CargoTomlNotFoundError(pub PathBuf); | 28 | pub struct CargoTomlNotFoundError(pub PathBuf); |
30 | 29 | ||
@@ -81,15 +80,36 @@ impl ProjectWorkspace { | |||
81 | ) -> Result<ProjectWorkspace> { | 80 | ) -> Result<ProjectWorkspace> { |
82 | match find_rust_project_json(path) { | 81 | match find_rust_project_json(path) { |
83 | Some(json_path) => { | 82 | Some(json_path) => { |
84 | let file = File::open(json_path)?; | 83 | let file = File::open(&json_path) |
84 | .with_context(|| format!("Failed to open json file {}", json_path.display()))?; | ||
85 | let reader = BufReader::new(file); | 85 | let reader = BufReader::new(file); |
86 | Ok(ProjectWorkspace::Json { project: from_reader(reader)? }) | 86 | Ok(ProjectWorkspace::Json { |
87 | project: from_reader(reader).with_context(|| { | ||
88 | format!("Failed to deserialize json file {}", json_path.display()) | ||
89 | })?, | ||
90 | }) | ||
87 | } | 91 | } |
88 | None => { | 92 | None => { |
89 | let cargo_toml = find_cargo_toml(path)?; | 93 | let cargo_toml = find_cargo_toml(path).with_context(|| { |
90 | let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_features)?; | 94 | format!("Failed to find Cargo.toml for path {}", path.display()) |
91 | let sysroot = | 95 | })?; |
92 | if with_sysroot { Sysroot::discover(&cargo_toml)? } else { Sysroot::default() }; | 96 | let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_features) |
97 | .with_context(|| { | ||
98 | format!( | ||
99 | "Failed to read Cargo metadata from Cargo.toml file {}", | ||
100 | cargo_toml.display() | ||
101 | ) | ||
102 | })?; | ||
103 | let sysroot = if with_sysroot { | ||
104 | Sysroot::discover(&cargo_toml).with_context(|| { | ||
105 | format!( | ||
106 | "Failed to find sysroot for Cargo.toml file {}", | ||
107 | cargo_toml.display() | ||
108 | ) | ||
109 | })? | ||
110 | } else { | ||
111 | Sysroot::default() | ||
112 | }; | ||
93 | Ok(ProjectWorkspace::Cargo { cargo, sysroot }) | 113 | Ok(ProjectWorkspace::Cargo { cargo, sysroot }) |
94 | } | 114 | } |
95 | } | 115 | } |
@@ -403,11 +423,20 @@ pub fn get_rustc_cfg_options() -> CfgOptions { | |||
403 | } | 423 | } |
404 | } | 424 | } |
405 | 425 | ||
406 | match (|| -> Result<_> { | 426 | match (|| -> Result<String> { |
407 | // `cfg(test)` and `cfg(debug_assertion)` are handled outside, so we suppress them here. | 427 | // `cfg(test)` and `cfg(debug_assertion)` are handled outside, so we suppress them here. |
408 | let output = Command::new("rustc").args(&["--print", "cfg", "-O"]).output()?; | 428 | let output = Command::new("rustc") |
429 | .args(&["--print", "cfg", "-O"]) | ||
430 | .output() | ||
431 | .context("Failed to get output from rustc --print cfg -O")?; | ||
409 | if !output.status.success() { | 432 | if !output.status.success() { |
410 | Err("failed to get rustc cfgs")?; | 433 | bail!( |
434 | "rustc --print cfg -O exited with exit code ({})", | ||
435 | output | ||
436 | .status | ||
437 | .code() | ||
438 | .map_or(String::from("no exit code"), |code| format!("{}", code)) | ||
439 | ); | ||
411 | } | 440 | } |
412 | Ok(String::from_utf8(output.stdout)?) | 441 | Ok(String::from_utf8(output.stdout)?) |
413 | })() { | 442 | })() { |
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs index a23265fc0..7b9cc899c 100644 --- a/crates/ra_project_model/src/sysroot.rs +++ b/crates/ra_project_model/src/sysroot.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use anyhow::{anyhow, bail, Context, Result}; | ||
3 | use std::{ | 4 | use std::{ |
4 | env, | 5 | env, |
5 | path::{Path, PathBuf}, | 6 | path::{Path, PathBuf}, |
@@ -8,8 +9,6 @@ use std::{ | |||
8 | 9 | ||
9 | use ra_arena::{impl_arena_id, Arena, RawId}; | 10 | use ra_arena::{impl_arena_id, Arena, RawId}; |
10 | 11 | ||
11 | use crate::Result; | ||
12 | |||
13 | #[derive(Default, Debug, Clone)] | 12 | #[derive(Default, Debug, Clone)] |
14 | pub struct Sysroot { | 13 | pub struct Sysroot { |
15 | crates: Arena<SysrootCrate, SysrootCrateData>, | 14 | crates: Arena<SysrootCrate, SysrootCrateData>, |
@@ -51,7 +50,7 @@ impl Sysroot { | |||
51 | let src = try_find_src_path(cargo_toml)?; | 50 | let src = try_find_src_path(cargo_toml)?; |
52 | 51 | ||
53 | if !src.exists() { | 52 | if !src.exists() { |
54 | Err(format!( | 53 | Err(anyhow!( |
55 | "can't load standard library from sysroot\n\ | 54 | "can't load standard library from sysroot\n\ |
56 | {}\n\ | 55 | {}\n\ |
57 | (discovered via `rustc --print sysroot`)\n\ | 56 | (discovered via `rustc --print sysroot`)\n\ |
@@ -100,9 +99,14 @@ fn try_find_src_path(cargo_toml: &Path) -> Result<PathBuf> { | |||
100 | .current_dir(cargo_toml.parent().unwrap()) | 99 | .current_dir(cargo_toml.parent().unwrap()) |
101 | .args(&["--print", "sysroot"]) | 100 | .args(&["--print", "sysroot"]) |
102 | .output() | 101 | .output() |
103 | .map_err(|e| format!("rustc --print sysroot failed: {}", e))?; | 102 | .context("rustc --print sysroot failed")?; |
104 | if !rustc_output.status.success() { | 103 | if !rustc_output.status.success() { |
105 | Err("failed to locate sysroot")?; | 104 | match rustc_output.status.code() { |
105 | Some(code) => { | ||
106 | bail!("failed to locate sysroot: rustc --print sysroot exited with code {}", code) | ||
107 | } | ||
108 | None => bail!("failed to locate sysroot: rustc --print sysroot terminated by signal"), | ||
109 | }; | ||
106 | } | 110 | } |
107 | let stdout = String::from_utf8(rustc_output.stdout)?; | 111 | let stdout = String::from_utf8(rustc_output.stdout)?; |
108 | let sysroot_path = Path::new(stdout.trim()); | 112 | let sysroot_path = Path::new(stdout.trim()); |
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rs b/crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rs new file mode 100644 index 000000000..1ebbe5b03 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rs | |||
@@ -0,0 +1 @@ | |||
type Foo = fn(_: bar); | |||
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.txt b/crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.txt new file mode 100644 index 000000000..52d8f21a4 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.txt | |||
@@ -0,0 +1,26 @@ | |||
1 | SOURCE_FILE@[0; 23) | ||
2 | TYPE_ALIAS_DEF@[0; 22) | ||
3 | TYPE_KW@[0; 4) "type" | ||
4 | WHITESPACE@[4; 5) " " | ||
5 | NAME@[5; 8) | ||
6 | IDENT@[5; 8) "Foo" | ||
7 | WHITESPACE@[8; 9) " " | ||
8 | EQ@[9; 10) "=" | ||
9 | WHITESPACE@[10; 11) " " | ||
10 | FN_POINTER_TYPE@[11; 21) | ||
11 | FN_KW@[11; 13) "fn" | ||
12 | PARAM_LIST@[13; 21) | ||
13 | L_PAREN@[13; 14) "(" | ||
14 | PARAM@[14; 20) | ||
15 | PLACEHOLDER_PAT@[14; 15) | ||
16 | UNDERSCORE@[14; 15) "_" | ||
17 | COLON@[15; 16) ":" | ||
18 | WHITESPACE@[16; 17) " " | ||
19 | PATH_TYPE@[17; 20) | ||
20 | PATH@[17; 20) | ||
21 | PATH_SEGMENT@[17; 20) | ||
22 | NAME_REF@[17; 20) | ||
23 | IDENT@[17; 20) "bar" | ||
24 | R_PAREN@[20; 21) ")" | ||
25 | SEMI@[21; 22) ";" | ||
26 | WHITESPACE@[22; 23) "\n" | ||