aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-03-06 13:44:44 +0000
committerAleksey Kladov <[email protected]>2020-03-06 13:44:44 +0000
commitfb5891c4330e577f5d6891be529141695ce36d4f (patch)
tree6c7f1384e77c29b9bdc3080acfbaadb1bcb01f0f
parentea0c124219da33462b9d0be93f7abe0478cc7af2 (diff)
Source map returns a result
cc #2236
-rw-r--r--crates/ra_db/src/fixture.rs4
-rw-r--r--crates/ra_hir/src/source_analyzer.rs4
-rw-r--r--crates/ra_hir_def/src/body.rs11
-rw-r--r--crates/ra_hir_ty/src/expr.rs4
-rw-r--r--crates/ra_hir_ty/src/tests.rs17
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs4
6 files changed, 26 insertions, 18 deletions
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs
index 17cd138c2..da7af110c 100644
--- a/crates/ra_db/src/fixture.rs
+++ b/crates/ra_db/src/fixture.rs
@@ -21,9 +21,9 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static {
21 (db, file_id) 21 (db, file_id)
22 } 22 }
23 23
24 fn with_files(fixture: &str) -> Self { 24 fn with_files(ra_fixture: &str) -> Self {
25 let mut db = Self::default(); 25 let mut db = Self::default();
26 let pos = with_files(&mut db, fixture); 26 let pos = with_files(&mut db, ra_fixture);
27 assert!(pos.is_none()); 27 assert!(pos.is_none());
28 db 28 db
29 } 29 }
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs
index f3f1ed05a..331ecdd9c 100644
--- a/crates/ra_hir/src/source_analyzer.rs
+++ b/crates/ra_hir/src/source_analyzer.rs
@@ -261,7 +261,7 @@ fn scope_for_offset(
261 .scope_by_expr() 261 .scope_by_expr()
262 .iter() 262 .iter()
263 .filter_map(|(id, scope)| { 263 .filter_map(|(id, scope)| {
264 let source = source_map.expr_syntax(*id)?; 264 let source = source_map.expr_syntax(*id).ok()?;
265 // FIXME: correctly handle macro expansion 265 // FIXME: correctly handle macro expansion
266 if source.file_id != offset.file_id { 266 if source.file_id != offset.file_id {
267 return None; 267 return None;
@@ -337,7 +337,7 @@ fn adjust(
337 .scope_by_expr() 337 .scope_by_expr()
338 .iter() 338 .iter()
339 .filter_map(|(id, scope)| { 339 .filter_map(|(id, scope)| {
340 let source = source_map.expr_syntax(*id)?; 340 let source = source_map.expr_syntax(*id).ok()?;
341 // FIXME: correctly handle macro expansion 341 // FIXME: correctly handle macro expansion
342 if source.file_id != file_id { 342 if source.file_id != file_id {
343 return None; 343 return None;
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index 010d35e55..cd9e22c42 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -156,6 +156,9 @@ pub struct BodySourceMap {
156 expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>, 156 expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>,
157} 157}
158 158
159#[derive(Debug)]
160pub struct SyntheticSyntax;
161
159impl Body { 162impl Body {
160 pub(crate) fn body_with_source_map_query( 163 pub(crate) fn body_with_source_map_query(
161 db: &impl DefDatabase, 164 db: &impl DefDatabase,
@@ -219,8 +222,8 @@ impl Index<PatId> for Body {
219} 222}
220 223
221impl BodySourceMap { 224impl BodySourceMap {
222 pub fn expr_syntax(&self, expr: ExprId) -> Option<ExprSource> { 225 pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> {
223 self.expr_map_back.get(expr).copied() 226 self.expr_map_back.get(expr).copied().ok_or(SyntheticSyntax)
224 } 227 }
225 228
226 pub fn node_expr(&self, node: InFile<&ast::Expr>) -> Option<ExprId> { 229 pub fn node_expr(&self, node: InFile<&ast::Expr>) -> Option<ExprId> {
@@ -238,8 +241,8 @@ impl BodySourceMap {
238 self.expr_map.get(&src).cloned() 241 self.expr_map.get(&src).cloned()
239 } 242 }
240 243
241 pub fn pat_syntax(&self, pat: PatId) -> Option<PatSource> { 244 pub fn pat_syntax(&self, pat: PatId) -> Result<PatSource, SyntheticSyntax> {
242 self.pat_map_back.get(pat).copied() 245 self.pat_map_back.get(pat).copied().ok_or(SyntheticSyntax)
243 } 246 }
244 247
245 pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> { 248 pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> {
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs
index 22f24890d..d8cdf5266 100644
--- a/crates/ra_hir_ty/src/expr.rs
+++ b/crates/ra_hir_ty/src/expr.rs
@@ -100,7 +100,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
100 } 100 }
101 let (_, source_map) = db.body_with_source_map(self.func.into()); 101 let (_, source_map) = db.body_with_source_map(self.func.into());
102 102
103 if let Some(source_ptr) = source_map.expr_syntax(id) { 103 if let Ok(source_ptr) = source_map.expr_syntax(id) {
104 if let Some(expr) = source_ptr.value.left() { 104 if let Some(expr) = source_ptr.value.left() {
105 let root = source_ptr.file_syntax(db); 105 let root = source_ptr.file_syntax(db);
106 if let ast::Expr::RecordLit(record_lit) = expr.to_node(&root) { 106 if let ast::Expr::RecordLit(record_lit) = expr.to_node(&root) {
@@ -145,7 +145,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
145 if params.len() == 2 && params[0] == mismatch.actual { 145 if params.len() == 2 && params[0] == mismatch.actual {
146 let (_, source_map) = db.body_with_source_map(self.func.into()); 146 let (_, source_map) = db.body_with_source_map(self.func.into());
147 147
148 if let Some(source_ptr) = source_map.expr_syntax(id) { 148 if let Ok(source_ptr) = source_map.expr_syntax(id) {
149 if let Some(expr) = source_ptr.value.left() { 149 if let Some(expr) = source_ptr.value.left() {
150 self.sink.push(MissingOkInTailExpr { file: source_ptr.file_id, expr }); 150 self.sink.push(MissingOkInTailExpr { file: source_ptr.file_id, expr });
151 } 151 }
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs
index 087edcc92..7e9547340 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -11,8 +11,13 @@ use std::fmt::Write;
11use std::sync::Arc; 11use std::sync::Arc;
12 12
13use hir_def::{ 13use hir_def::{
14 body::BodySourceMap, child_by_source::ChildBySource, db::DefDatabase, item_scope::ItemScope, 14 body::{BodySourceMap, SyntheticSyntax},
15 keys, nameres::CrateDefMap, AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId, 15 child_by_source::ChildBySource,
16 db::DefDatabase,
17 item_scope::ItemScope,
18 keys,
19 nameres::CrateDefMap,
20 AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId,
16}; 21};
17use hir_expand::InFile; 22use hir_expand::InFile;
18use insta::assert_snapshot; 23use insta::assert_snapshot;
@@ -67,20 +72,20 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
67 72
68 for (pat, ty) in inference_result.type_of_pat.iter() { 73 for (pat, ty) in inference_result.type_of_pat.iter() {
69 let syntax_ptr = match body_source_map.pat_syntax(pat) { 74 let syntax_ptr = match body_source_map.pat_syntax(pat) {
70 Some(sp) => { 75 Ok(sp) => {
71 sp.map(|ast| ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr())) 76 sp.map(|ast| ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()))
72 } 77 }
73 None => continue, 78 Err(SyntheticSyntax) => continue,
74 }; 79 };
75 types.push((syntax_ptr, ty)); 80 types.push((syntax_ptr, ty));
76 } 81 }
77 82
78 for (expr, ty) in inference_result.type_of_expr.iter() { 83 for (expr, ty) in inference_result.type_of_expr.iter() {
79 let syntax_ptr = match body_source_map.expr_syntax(expr) { 84 let syntax_ptr = match body_source_map.expr_syntax(expr) {
80 Some(sp) => { 85 Ok(sp) => {
81 sp.map(|ast| ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr())) 86 sp.map(|ast| ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()))
82 } 87 }
83 None => continue, 88 Err(SyntheticSyntax) => continue,
84 }; 89 };
85 types.push((syntax_ptr, ty)); 90 types.push((syntax_ptr, ty));
86 if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr) { 91 if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr) {
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index 6bf0be565..643c54a9d 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -158,7 +158,7 @@ pub fn analysis_stats(
158 // in super-verbose mode for just one function, we print every single expression 158 // in super-verbose mode for just one function, we print every single expression
159 let (_, sm) = db.body_with_source_map(f_id.into()); 159 let (_, sm) = db.body_with_source_map(f_id.into());
160 let src = sm.expr_syntax(expr_id); 160 let src = sm.expr_syntax(expr_id);
161 if let Some(src) = src { 161 if let Ok(src) = src {
162 let original_file = src.file_id.original_file(db); 162 let original_file = src.file_id.original_file(db);
163 let line_index = host.analysis().file_line_index(original_file).unwrap(); 163 let line_index = host.analysis().file_line_index(original_file).unwrap();
164 let text_range = src.value.either( 164 let text_range = src.value.either(
@@ -186,7 +186,7 @@ pub fn analysis_stats(
186 if verbosity.is_verbose() { 186 if verbosity.is_verbose() {
187 let (_, sm) = db.body_with_source_map(f_id.into()); 187 let (_, sm) = db.body_with_source_map(f_id.into());
188 let src = sm.expr_syntax(expr_id); 188 let src = sm.expr_syntax(expr_id);
189 if let Some(src) = src { 189 if let Ok(src) = src {
190 // FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly 190 // FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly
191 // But also, we should just turn the type mismatches into diagnostics and provide these 191 // But also, we should just turn the type mismatches into diagnostics and provide these
192 let root = db.parse_or_expand(src.file_id).unwrap(); 192 let root = db.parse_or_expand(src.file_id).unwrap();