Skip to content

Commit 1a1c09e

Browse files
bors[bot]matklad
andauthored
Merge #3951
3951: Simplify records grammar r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
2 parents 11d400b + 0aece75 commit 1a1c09e

File tree

17 files changed

+180
-121
lines changed

17 files changed

+180
-121
lines changed

crates/ra_hir/src/source_analyzer.rs

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ impl SourceAnalyzer {
139139
&self,
140140
db: &dyn HirDatabase,
141141
field: &ast::FieldExpr,
142-
) -> Option<crate::StructField> {
142+
) -> Option<StructField> {
143143
let expr_id = self.expr_id(db, &field.clone().into())?;
144144
self.infer.as_ref()?.field_resolution(expr_id).map(|it| it.into())
145145
}
@@ -148,21 +148,19 @@ impl SourceAnalyzer {
148148
&self,
149149
db: &dyn HirDatabase,
150150
field: &ast::RecordField,
151-
) -> Option<(crate::StructField, Option<Local>)> {
152-
let (expr_id, local) = match field.expr() {
153-
Some(it) => (self.expr_id(db, &it)?, None),
154-
None => {
155-
let src = InFile { file_id: self.file_id, value: field };
156-
let expr_id = self.body_source_map.as_ref()?.field_init_shorthand_expr(src)?;
157-
let local_name = field.name_ref()?.as_name();
158-
let path = ModPath::from_segments(PathKind::Plain, once(local_name));
159-
let local = match self.resolver.resolve_path_in_value_ns_fully(db.upcast(), &path) {
160-
Some(ValueNs::LocalBinding(pat_id)) => {
161-
Some(Local { pat_id, parent: self.resolver.body_owner()? })
162-
}
163-
_ => None,
164-
};
165-
(expr_id, local)
151+
) -> Option<(StructField, Option<Local>)> {
152+
let expr = field.expr()?;
153+
let expr_id = self.expr_id(db, &expr)?;
154+
let local = if field.name_ref().is_some() {
155+
None
156+
} else {
157+
let local_name = field.field_name()?.as_name();
158+
let path = ModPath::from_segments(PathKind::Plain, once(local_name));
159+
match self.resolver.resolve_path_in_value_ns_fully(db.upcast(), &path) {
160+
Some(ValueNs::LocalBinding(pat_id)) => {
161+
Some(Local { pat_id, parent: self.resolver.body_owner()? })
162+
}
163+
_ => None,
166164
}
167165
};
168166
let struct_field = self.infer.as_ref()?.record_field_resolution(expr_id)?;
@@ -319,8 +317,7 @@ fn scope_for_offset(
319317
if source.file_id != offset.file_id {
320318
return None;
321319
}
322-
let syntax_node_ptr =
323-
source.value.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr());
320+
let syntax_node_ptr = source.value.syntax_node_ptr();
324321
Some((syntax_node_ptr, scope))
325322
})
326323
// find containing scope
@@ -399,8 +396,7 @@ fn adjust(
399396
if source.file_id != file_id {
400397
return None;
401398
}
402-
let syntax_node_ptr =
403-
source.value.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr());
399+
let syntax_node_ptr = source.value.syntax_node_ptr();
404400
Some((syntax_node_ptr, scope))
405401
})
406402
.map(|(ptr, scope)| (ptr.range(), scope))

crates/ra_hir_def/src/body.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use drop_bomb::DropBomb;
99
use either::Either;
1010
use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile, MacroDefId};
1111
use ra_arena::{map::ArenaMap, Arena};
12+
use ra_cfg::CfgOptions;
13+
use ra_db::CrateId;
1214
use ra_prof::profile;
1315
use ra_syntax::{ast, AstNode, AstPtr};
1416
use rustc_hash::FxHashMap;
@@ -24,8 +26,6 @@ use crate::{
2426
src::HasSource,
2527
AsMacroCall, DefWithBodyId, HasModule, Lookup, ModuleId,
2628
};
27-
use ra_cfg::CfgOptions;
28-
use ra_db::CrateId;
2929

3030
/// A subser of Exander that only deals with cfg attributes. We only need it to
3131
/// avoid cyclic queries in crate def map during enum processing.
@@ -187,7 +187,7 @@ pub struct Body {
187187
pub item_scope: ItemScope,
188188
}
189189

190-
pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>;
190+
pub type ExprPtr = AstPtr<ast::Expr>;
191191
pub type ExprSource = InFile<ExprPtr>;
192192

193193
pub type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>;
@@ -285,7 +285,7 @@ impl BodySourceMap {
285285
}
286286

287287
pub fn node_expr(&self, node: InFile<&ast::Expr>) -> Option<ExprId> {
288-
let src = node.map(|it| Either::Left(AstPtr::new(it)));
288+
let src = node.map(|it| AstPtr::new(it));
289289
self.expr_map.get(&src).cloned()
290290
}
291291

@@ -294,11 +294,6 @@ impl BodySourceMap {
294294
self.expansions.get(&src).cloned()
295295
}
296296

297-
pub fn field_init_shorthand_expr(&self, node: InFile<&ast::RecordField>) -> Option<ExprId> {
298-
let src = node.map(|it| Either::Right(AstPtr::new(it)));
299-
self.expr_map.get(&src).cloned()
300-
}
301-
302297
pub fn pat_syntax(&self, pat: PatId) -> Result<PatSource, SyntheticSyntax> {
303298
self.pat_map_back[pat].clone()
304299
}

crates/ra_hir_def/src/body/lower.rs

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ use crate::{
2727
},
2828
item_scope::BuiltinShadowMode,
2929
path::GenericArgs,
30-
path::Path,
3130
type_ref::{Mutability, TypeRef},
3231
AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId,
3332
StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
@@ -102,7 +101,6 @@ impl ExprCollector<'_> {
102101
}
103102

104103
fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId {
105-
let ptr = Either::Left(ptr);
106104
let src = self.expander.to_source(ptr);
107105
let id = self.make_expr(expr, Ok(src.clone()));
108106
self.source_map.expr_map.insert(src, id);
@@ -113,13 +111,6 @@ impl ExprCollector<'_> {
113111
fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId {
114112
self.make_expr(expr, Err(SyntheticSyntax))
115113
}
116-
fn alloc_expr_field_shorthand(&mut self, expr: Expr, ptr: AstPtr<ast::RecordField>) -> ExprId {
117-
let ptr = Either::Right(ptr);
118-
let src = self.expander.to_source(ptr);
119-
let id = self.make_expr(expr, Ok(src.clone()));
120-
self.source_map.expr_map.insert(src, id);
121-
id
122-
}
123114
fn empty_block(&mut self) -> ExprId {
124115
self.alloc_expr_desugared(Expr::Block { statements: Vec::new(), tail: None })
125116
}
@@ -289,7 +280,7 @@ impl ExprCollector<'_> {
289280
ast::Expr::ParenExpr(e) => {
290281
let inner = self.collect_expr_opt(e.expr());
291282
// make the paren expr point to the inner expression as well
292-
let src = self.expander.to_source(Either::Left(syntax_ptr));
283+
let src = self.expander.to_source(syntax_ptr);
293284
self.source_map.expr_map.insert(src, inner);
294285
inner
295286
}
@@ -309,22 +300,13 @@ impl ExprCollector<'_> {
309300
if !self.expander.is_cfg_enabled(&attrs) {
310301
return None;
311302
}
303+
let name = field.field_name()?.as_name();
312304

313305
Some(RecordLitField {
314-
name: field
315-
.name_ref()
316-
.map(|nr| nr.as_name())
317-
.unwrap_or_else(Name::missing),
318-
expr: if let Some(e) = field.expr() {
319-
self.collect_expr(e)
320-
} else if let Some(nr) = field.name_ref() {
321-
// field shorthand
322-
self.alloc_expr_field_shorthand(
323-
Expr::Path(Path::from_name_ref(&nr)),
324-
AstPtr::new(&field),
325-
)
326-
} else {
327-
self.missing_expr()
306+
name,
307+
expr: match field.expr() {
308+
Some(e) => self.collect_expr(e),
309+
None => self.missing_expr(),
328310
},
329311
})
330312
})

crates/ra_hir_def/src/path.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,6 @@ impl Path {
134134
lower::lower_path(path, hygiene)
135135
}
136136

137-
/// Converts an `ast::NameRef` into a single-identifier `Path`.
138-
pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> Path {
139-
Path { type_anchor: None, mod_path: name_ref.as_name().into(), generic_args: vec![None] }
140-
}
141-
142137
/// Converts a known mod path to `Path`.
143138
pub(crate) fn from_known_path(
144139
path: ModPath,

crates/ra_hir_ty/src/expr.rs

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -89,21 +89,19 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
8989
let (_, source_map) = db.body_with_source_map(self.func.into());
9090

9191
if let Ok(source_ptr) = source_map.expr_syntax(id) {
92-
if let Some(expr) = source_ptr.value.as_ref().left() {
93-
let root = source_ptr.file_syntax(db.upcast());
94-
if let ast::Expr::RecordLit(record_lit) = expr.to_node(&root) {
95-
if let Some(field_list) = record_lit.record_field_list() {
96-
let variant_data = variant_data(db.upcast(), variant_def);
97-
let missed_fields = missed_fields
98-
.into_iter()
99-
.map(|idx| variant_data.fields()[idx].name.clone())
100-
.collect();
101-
self.sink.push(MissingFields {
102-
file: source_ptr.file_id,
103-
field_list: AstPtr::new(&field_list),
104-
missed_fields,
105-
})
106-
}
92+
let root = source_ptr.file_syntax(db.upcast());
93+
if let ast::Expr::RecordLit(record_lit) = &source_ptr.value.to_node(&root) {
94+
if let Some(field_list) = record_lit.record_field_list() {
95+
let variant_data = variant_data(db.upcast(), variant_def);
96+
let missed_fields = missed_fields
97+
.into_iter()
98+
.map(|idx| variant_data.fields()[idx].name.clone())
99+
.collect();
100+
self.sink.push(MissingFields {
101+
file: source_ptr.file_id,
102+
field_list: AstPtr::new(&field_list),
103+
missed_fields,
104+
})
107105
}
108106
}
109107
}
@@ -205,18 +203,16 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
205203
}
206204

207205
if let Ok(source_ptr) = source_map.expr_syntax(id) {
208-
if let Some(expr) = source_ptr.value.as_ref().left() {
209-
let root = source_ptr.file_syntax(db.upcast());
210-
if let ast::Expr::MatchExpr(match_expr) = expr.to_node(&root) {
211-
if let (Some(match_expr), Some(arms)) =
212-
(match_expr.expr(), match_expr.match_arm_list())
213-
{
214-
self.sink.push(MissingMatchArms {
215-
file: source_ptr.file_id,
216-
match_expr: AstPtr::new(&match_expr),
217-
arms: AstPtr::new(&arms),
218-
})
219-
}
206+
let root = source_ptr.file_syntax(db.upcast());
207+
if let ast::Expr::MatchExpr(match_expr) = &source_ptr.value.to_node(&root) {
208+
if let (Some(match_expr), Some(arms)) =
209+
(match_expr.expr(), match_expr.match_arm_list())
210+
{
211+
self.sink.push(MissingMatchArms {
212+
file: source_ptr.file_id,
213+
match_expr: AstPtr::new(&match_expr),
214+
arms: AstPtr::new(&arms),
215+
})
220216
}
221217
}
222218
}
@@ -247,9 +243,8 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
247243
let (_, source_map) = db.body_with_source_map(self.func.into());
248244

249245
if let Ok(source_ptr) = source_map.expr_syntax(id) {
250-
if let Some(expr) = source_ptr.value.left() {
251-
self.sink.push(MissingOkInTailExpr { file: source_ptr.file_id, expr });
252-
}
246+
self.sink
247+
.push(MissingOkInTailExpr { file: source_ptr.file_id, expr: source_ptr.value });
253248
}
254249
}
255250
}

crates/ra_hir_ty/src/tests.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
8282

8383
for (expr, ty) in inference_result.type_of_expr.iter() {
8484
let syntax_ptr = match body_source_map.expr_syntax(expr) {
85-
Ok(sp) => {
86-
sp.map(|ast| ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()))
87-
}
85+
Ok(sp) => sp.map(|ast| ast.syntax_node_ptr()),
8886
Err(SyntheticSyntax) => continue,
8987
};
9088
types.push((syntax_ptr.clone(), ty));

crates/ra_ide/src/completion/complete_unqualified_path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::completion::{CompletionContext, Completions};
44

55
pub(super) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
6-
if !(ctx.is_trivial_path && !ctx.is_pat_binding_or_const) {
6+
if !(ctx.is_trivial_path && !ctx.is_pat_binding_or_const && !ctx.record_lit_syntax.is_some()) {
77
return;
88
}
99

crates/ra_ide/src/completion/completion_context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ impl<'a> CompletionContext<'a> {
227227
self.name_ref_syntax =
228228
find_node_at_offset(&original_file, name_ref.syntax().text_range().start());
229229
let name_range = name_ref.syntax().text_range();
230-
if name_ref.syntax().parent().and_then(ast::RecordField::cast).is_some() {
230+
if ast::RecordField::for_field_name(&name_ref).is_some() {
231231
self.record_lit_syntax =
232232
self.sema.find_node_at_offset_with_macros(&original_file, offset);
233233
}

crates/ra_ide_db/src/defs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ pub fn classify_name_ref(
216216
}
217217
}
218218

219-
if let Some(record_field) = ast::RecordField::cast(parent.clone()) {
219+
if let Some(record_field) = ast::RecordField::for_field_name(name_ref) {
220220
tested_by!(goto_def_for_record_fields; force);
221221
tested_by!(goto_def_for_field_init_shorthand; force);
222222
if let Some((field, local)) = sema.resolve_record_field(&record_field) {

crates/ra_parser/src/grammar/expressions.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -619,26 +619,39 @@ pub(crate) fn record_field_list(p: &mut Parser) {
619619
let m = p.start();
620620
p.bump(T!['{']);
621621
while !p.at(EOF) && !p.at(T!['}']) {
622+
let m = p.start();
623+
// test record_literal_field_with_attr
624+
// fn main() {
625+
// S { #[cfg(test)] field: 1 }
626+
// }
627+
attributes::outer_attributes(p);
628+
622629
match p.current() {
623-
// test record_literal_field_with_attr
624-
// fn main() {
625-
// S { #[cfg(test)] field: 1 }
626-
// }
627-
IDENT | INT_NUMBER | T![#] => {
628-
let m = p.start();
629-
attributes::outer_attributes(p);
630-
name_ref_or_index(p);
631-
if p.eat(T![:]) {
632-
expr(p);
630+
IDENT | INT_NUMBER => {
631+
// test_err record_literal_before_ellipsis_recovery
632+
// fn main() {
633+
// S { field ..S::default() }
634+
// }
635+
if p.nth_at(1, T![:]) || p.nth_at(1, T![..]) {
636+
name_ref_or_index(p);
637+
p.expect(T![:]);
633638
}
639+
expr(p);
634640
m.complete(p, RECORD_FIELD);
635641
}
636642
T![.] if p.at(T![..]) => {
643+
m.abandon(p);
637644
p.bump(T![..]);
638645
expr(p);
639646
}
640-
T!['{'] => error_block(p, "expected a field"),
641-
_ => p.err_and_bump("expected identifier"),
647+
T!['{'] => {
648+
error_block(p, "expected a field");
649+
m.abandon(p);
650+
}
651+
_ => {
652+
p.err_and_bump("expected identifier");
653+
m.abandon(p);
654+
}
642655
}
643656
if !p.at(T!['}']) {
644657
p.expect(T![,]);

0 commit comments

Comments
 (0)