Skip to content

Commit 1cc6879

Browse files
bors[bot]matklad
andauthored
Merge #3489
3489: More robust expression lowering r=matklad a=matklad Closes #2236 Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2 parents 5947c1f + 57da3df commit 1cc6879

File tree

7 files changed

+51
-38
lines changed

7 files changed

+51
-38
lines changed

crates/ra_db/src/fixture.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static {
2121
(db, file_id)
2222
}
2323

24-
fn with_files(fixture: &str) -> Self {
24+
fn with_files(ra_fixture: &str) -> Self {
2525
let mut db = Self::default();
26-
let pos = with_files(&mut db, fixture);
26+
let pos = with_files(&mut db, ra_fixture);
2727
assert!(pos.is_none());
2828
db
2929
}

crates/ra_hir/src/source_analyzer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ fn scope_for_offset(
261261
.scope_by_expr()
262262
.iter()
263263
.filter_map(|(id, scope)| {
264-
let source = source_map.expr_syntax(*id)?;
264+
let source = source_map.expr_syntax(*id).ok()?;
265265
// FIXME: correctly handle macro expansion
266266
if source.file_id != offset.file_id {
267267
return None;
@@ -337,7 +337,7 @@ fn adjust(
337337
.scope_by_expr()
338338
.iter()
339339
.filter_map(|(id, scope)| {
340-
let source = source_map.expr_syntax(*id)?;
340+
let source = source_map.expr_syntax(*id).ok()?;
341341
// FIXME: correctly handle macro expansion
342342
if source.file_id != file_id {
343343
return None;

crates/ra_hir_def/src/body.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,16 @@ pub type PatSource = InFile<PatPtr>;
149149
#[derive(Default, Debug, Eq, PartialEq)]
150150
pub struct BodySourceMap {
151151
expr_map: FxHashMap<ExprSource, ExprId>,
152-
expr_map_back: ArenaMap<ExprId, ExprSource>,
152+
expr_map_back: ArenaMap<ExprId, Result<ExprSource, SyntheticSyntax>>,
153153
pat_map: FxHashMap<PatSource, PatId>,
154-
pat_map_back: ArenaMap<PatId, PatSource>,
154+
pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>,
155155
field_map: FxHashMap<(ExprId, usize), AstPtr<ast::RecordField>>,
156156
expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>,
157157
}
158158

159+
#[derive(Default, Debug, Eq, PartialEq, Clone, Copy)]
160+
pub struct SyntheticSyntax;
161+
159162
impl Body {
160163
pub(crate) fn body_with_source_map_query(
161164
db: &impl DefDatabase,
@@ -219,8 +222,8 @@ impl Index<PatId> for Body {
219222
}
220223

221224
impl BodySourceMap {
222-
pub fn expr_syntax(&self, expr: ExprId) -> Option<ExprSource> {
223-
self.expr_map_back.get(expr).copied()
225+
pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> {
226+
self.expr_map_back[expr]
224227
}
225228

226229
pub fn node_expr(&self, node: InFile<&ast::Expr>) -> Option<ExprId> {
@@ -238,8 +241,8 @@ impl BodySourceMap {
238241
self.expr_map.get(&src).cloned()
239242
}
240243

241-
pub fn pat_syntax(&self, pat: PatId) -> Option<PatSource> {
242-
self.pat_map_back.get(pat).copied()
244+
pub fn pat_syntax(&self, pat: PatId) -> Result<PatSource, SyntheticSyntax> {
245+
self.pat_map_back[pat]
243246
}
244247

245248
pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> {

crates/ra_hir_def/src/body/lower.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ use ra_syntax::{
1414
};
1515
use test_utils::tested_by;
1616

17+
use super::{ExprSource, PatSource};
1718
use crate::{
1819
adt::StructKind,
19-
body::{Body, BodySourceMap, Expander, PatPtr},
20+
body::{Body, BodySourceMap, Expander, PatPtr, SyntheticSyntax},
2021
builtin_type::{BuiltinFloat, BuiltinInt},
2122
db::DefDatabase,
2223
expr::{
@@ -102,44 +103,48 @@ where
102103

103104
fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId {
104105
let ptr = Either::Left(ptr);
105-
let id = self.body.exprs.alloc(expr);
106106
let src = self.expander.to_source(ptr);
107+
let id = self.make_expr(expr, Ok(src));
107108
self.source_map.expr_map.insert(src, id);
108-
self.source_map.expr_map_back.insert(id, src);
109109
id
110110
}
111111
// desugared exprs don't have ptr, that's wrong and should be fixed
112112
// somehow.
113113
fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId {
114-
self.body.exprs.alloc(expr)
114+
self.make_expr(expr, Err(SyntheticSyntax))
115115
}
116116
fn alloc_expr_field_shorthand(&mut self, expr: Expr, ptr: AstPtr<ast::RecordField>) -> ExprId {
117117
let ptr = Either::Right(ptr);
118-
let id = self.body.exprs.alloc(expr);
119118
let src = self.expander.to_source(ptr);
119+
let id = self.make_expr(expr, Ok(src));
120120
self.source_map.expr_map.insert(src, id);
121+
id
122+
}
123+
fn empty_block(&mut self) -> ExprId {
124+
self.alloc_expr_desugared(Expr::Block { statements: Vec::new(), tail: None })
125+
}
126+
fn missing_expr(&mut self) -> ExprId {
127+
self.alloc_expr_desugared(Expr::Missing)
128+
}
129+
fn make_expr(&mut self, expr: Expr, src: Result<ExprSource, SyntheticSyntax>) -> ExprId {
130+
let id = self.body.exprs.alloc(expr);
121131
self.source_map.expr_map_back.insert(id, src);
122132
id
123133
}
134+
124135
fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId {
125-
let id = self.body.pats.alloc(pat);
126136
let src = self.expander.to_source(ptr);
137+
let id = self.make_pat(pat, Ok(src));
127138
self.source_map.pat_map.insert(src, id);
128-
self.source_map.pat_map_back.insert(id, src);
129139
id
130140
}
131-
132-
fn empty_block(&mut self) -> ExprId {
133-
let block = Expr::Block { statements: Vec::new(), tail: None };
134-
self.body.exprs.alloc(block)
135-
}
136-
137-
fn missing_expr(&mut self) -> ExprId {
138-
self.body.exprs.alloc(Expr::Missing)
139-
}
140-
141141
fn missing_pat(&mut self) -> PatId {
142-
self.body.pats.alloc(Pat::Missing)
142+
self.make_pat(Pat::Missing, Err(SyntheticSyntax))
143+
}
144+
fn make_pat(&mut self, pat: Pat, src: Result<PatSource, SyntheticSyntax>) -> PatId {
145+
let id = self.body.pats.alloc(pat);
146+
self.source_map.pat_map_back.insert(id, src);
147+
id
143148
}
144149

145150
fn collect_expr(&mut self, expr: ast::Expr) -> ExprId {

crates/ra_hir_ty/src/expr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
100100
}
101101
let (_, source_map) = db.body_with_source_map(self.func.into());
102102

103-
if let Some(source_ptr) = source_map.expr_syntax(id) {
103+
if let Ok(source_ptr) = source_map.expr_syntax(id) {
104104
if let Some(expr) = source_ptr.value.left() {
105105
let root = source_ptr.file_syntax(db);
106106
if let ast::Expr::RecordLit(record_lit) = expr.to_node(&root) {
@@ -145,7 +145,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
145145
if params.len() == 2 && params[0] == mismatch.actual {
146146
let (_, source_map) = db.body_with_source_map(self.func.into());
147147

148-
if let Some(source_ptr) = source_map.expr_syntax(id) {
148+
if let Ok(source_ptr) = source_map.expr_syntax(id) {
149149
if let Some(expr) = source_ptr.value.left() {
150150
self.sink.push(MissingOkInTailExpr { file: source_ptr.file_id, expr });
151151
}

crates/ra_hir_ty/src/tests.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,13 @@ use std::fmt::Write;
1111
use std::sync::Arc;
1212

1313
use hir_def::{
14-
body::BodySourceMap, child_by_source::ChildBySource, db::DefDatabase, item_scope::ItemScope,
15-
keys, nameres::CrateDefMap, AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId,
14+
body::{BodySourceMap, SyntheticSyntax},
15+
child_by_source::ChildBySource,
16+
db::DefDatabase,
17+
item_scope::ItemScope,
18+
keys,
19+
nameres::CrateDefMap,
20+
AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId,
1621
};
1722
use hir_expand::InFile;
1823
use insta::assert_snapshot;
@@ -67,20 +72,20 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
6772

6873
for (pat, ty) in inference_result.type_of_pat.iter() {
6974
let syntax_ptr = match body_source_map.pat_syntax(pat) {
70-
Some(sp) => {
75+
Ok(sp) => {
7176
sp.map(|ast| ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()))
7277
}
73-
None => continue,
78+
Err(SyntheticSyntax) => continue,
7479
};
7580
types.push((syntax_ptr, ty));
7681
}
7782

7883
for (expr, ty) in inference_result.type_of_expr.iter() {
7984
let syntax_ptr = match body_source_map.expr_syntax(expr) {
80-
Some(sp) => {
85+
Ok(sp) => {
8186
sp.map(|ast| ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()))
8287
}
83-
None => continue,
88+
Err(SyntheticSyntax) => continue,
8489
};
8590
types.push((syntax_ptr, ty));
8691
if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr) {

crates/rust-analyzer/src/cli/analysis_stats.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ pub fn analysis_stats(
158158
// in super-verbose mode for just one function, we print every single expression
159159
let (_, sm) = db.body_with_source_map(f_id.into());
160160
let src = sm.expr_syntax(expr_id);
161-
if let Some(src) = src {
161+
if let Ok(src) = src {
162162
let original_file = src.file_id.original_file(db);
163163
let line_index = host.analysis().file_line_index(original_file).unwrap();
164164
let text_range = src.value.either(
@@ -186,7 +186,7 @@ pub fn analysis_stats(
186186
if verbosity.is_verbose() {
187187
let (_, sm) = db.body_with_source_map(f_id.into());
188188
let src = sm.expr_syntax(expr_id);
189-
if let Some(src) = src {
189+
if let Ok(src) = src {
190190
// FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly
191191
// But also, we should just turn the type mismatches into diagnostics and provide these
192192
let root = db.parse_or_expand(src.file_id).unwrap();

0 commit comments

Comments
 (0)