Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 2622160

Browse files
committed
Merge record lit's ellipsis into pre-existing spread's variant
1 parent 5ca9f52 commit 2622160

File tree

10 files changed

+55
-34
lines changed

10 files changed

+55
-34
lines changed

src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::{
2525
db::DefDatabase,
2626
hir::{
2727
Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label, LabelId, Pat,
28-
PatId, RecordFieldPat, Statement,
28+
PatId, RecordFieldPat, Spread, Statement,
2929
},
3030
nameres::DefMap,
3131
path::{ModPath, Path},
@@ -362,7 +362,7 @@ impl ExpressionStore {
362362
for field in fields.iter() {
363363
f(field.expr);
364364
}
365-
if let &Some(expr) = spread {
365+
if let &Spread::Base(expr) = spread {
366366
f(expr);
367367
}
368368
}
@@ -490,7 +490,7 @@ impl ExpressionStore {
490490
for field in fields.iter() {
491491
f(field.expr);
492492
}
493-
if let &Some(expr) = spread {
493+
if let &Spread::Base(expr) = spread {
494494
f(expr);
495495
}
496496
}

src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use crate::{
4545
},
4646
Array, Binding, BindingAnnotation, BindingId, BindingProblems, CaptureBy, ClosureKind,
4747
Expr, ExprId, Item, Label, LabelId, Literal, LiteralOrConst, MatchArm, Movability,
48-
OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
48+
OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, Spread, Statement,
4949
},
5050
item_scope::BuiltinShadowMode,
5151
lang_item::LangItem,
@@ -602,11 +602,13 @@ impl ExprCollector<'_> {
602602
Some(RecordLitField { name, expr })
603603
})
604604
.collect();
605-
let spread = nfl.spread().map(|s| self.collect_expr(s));
606-
let ellipsis = nfl.dotdot_token().is_some();
607-
Expr::RecordLit { path, fields, spread, ellipsis }
605+
let spread = nfl.spread().map(|s| self.collect_expr(s)).map_or_else(
606+
|| if nfl.dotdot_token().is_some() { Spread::Yes } else { Spread::No },
607+
Spread::Base,
608+
);
609+
Expr::RecordLit { path, fields, spread }
608610
} else {
609-
Expr::RecordLit { path, fields: Box::default(), spread: None, ellipsis: false }
611+
Expr::RecordLit { path, fields: Box::default(), spread: Spread::No }
610612
};
611613

612614
self.alloc_expr(record_lit, syntax_ptr)

src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use span::Edition;
88
use crate::{
99
hir::{
1010
Array, BindingAnnotation, CaptureBy, ClosureKind, Literal, LiteralOrConst, Movability,
11-
Statement,
11+
Spread, Statement,
1212
},
1313
pretty::{print_generic_args, print_path, print_type_ref},
1414
VariantId,
@@ -398,7 +398,7 @@ impl Printer<'_> {
398398
self.print_expr(*expr);
399399
}
400400
}
401-
Expr::RecordLit { path, fields, spread, ellipsis: _ } => {
401+
Expr::RecordLit { path, fields, spread } => {
402402
match path {
403403
Some(path) => self.print_path(path),
404404
None => w!(self, "�"),
@@ -412,10 +412,16 @@ impl Printer<'_> {
412412
p.print_expr(field.expr);
413413
wln!(p, ",");
414414
}
415-
if let Some(spread) = spread {
416-
w!(p, "..");
417-
p.print_expr(*spread);
418-
wln!(p);
415+
match spread {
416+
Spread::No => {}
417+
Spread::Yes => {
418+
w!(p, "..");
419+
}
420+
Spread::Base(expr) => {
421+
w!(p, "..");
422+
p.print_expr(*expr);
423+
wln!(p);
424+
}
419425
}
420426
});
421427
w!(self, "}}");

src/tools/rust-analyzer/crates/hir-def/src/hir.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,7 @@ pub enum Expr {
251251
RecordLit {
252252
path: Option<Box<Path>>,
253253
fields: Box<[RecordLitField]>,
254-
spread: Option<ExprId>,
255-
ellipsis: bool,
254+
spread: Spread,
256255
},
257256
Field {
258257
expr: ExprId,
@@ -479,6 +478,13 @@ pub struct RecordLitField {
479478
pub expr: ExprId,
480479
}
481480

481+
#[derive(Debug, Clone, Eq, PartialEq)]
482+
pub enum Spread {
483+
No,
484+
Yes,
485+
Base(ExprId),
486+
}
487+
482488
#[derive(Debug, Clone, Eq, PartialEq)]
483489
pub enum Statement {
484490
Let {

src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use base_db::CrateId;
88
use chalk_solve::rust_ir::AdtKind;
99
use either::Either;
1010
use hir_def::{
11+
hir::Spread,
1112
lang_item::LangItem,
1213
resolver::{HasResolver, ValueNs},
1314
AdtId, AssocItemId, DefWithBodyId, HasModule, ItemContainerId, Lookup,
@@ -546,9 +547,11 @@ pub fn record_literal_missing_fields(
546547
infer: &InferenceResult,
547548
id: ExprId,
548549
expr: &Expr,
549-
) -> Option<(VariantId, Vec<LocalFieldId>, /*exhaustive*/ bool)> {
550-
let (fields, exhaustive, ellipsis) = match expr {
551-
Expr::RecordLit { fields, spread, ellipsis, .. } => (fields, spread.is_none(), *ellipsis),
550+
) -> Option<(VariantId, Vec<LocalFieldId>, /*has spread expr*/ bool)> {
551+
let (fields, has_spread_expr, has_ellipsis) = match expr {
552+
Expr::RecordLit { fields, spread, .. } => {
553+
(fields, matches!(spread, Spread::Base(_)), matches!(spread, Spread::Yes))
554+
}
552555
_ => return None,
553556
};
554557

@@ -564,7 +567,7 @@ pub fn record_literal_missing_fields(
564567
.fields()
565568
.iter()
566569
.filter_map(|(f, d)| {
567-
if (ellipsis && d.has_default) || specified_fields.contains(&d.name) {
570+
if (has_ellipsis && d.has_default) || specified_fields.contains(&d.name) {
568571
None
569572
} else {
570573
Some(f)
@@ -574,7 +577,7 @@ pub fn record_literal_missing_fields(
574577
if missed_fields.is_empty() {
575578
return None;
576579
}
577-
Some((variant_def, missed_fields, exhaustive))
580+
Some((variant_def, missed_fields, has_spread_expr))
578581
}
579582

580583
pub fn record_pattern_missing_fields(

src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use hir_def::{
1212
data::adt::VariantData,
1313
hir::{
1414
Array, AsmOperand, BinaryOp, BindingId, CaptureBy, Expr, ExprId, ExprOrPatId, Pat, PatId,
15-
Statement, UnaryOp,
15+
Spread, Statement, UnaryOp,
1616
},
1717
lang_item::LangItem,
1818
path::Path,
@@ -796,7 +796,7 @@ impl InferenceContext<'_> {
796796
self.consume_expr(expr);
797797
}
798798
Expr::RecordLit { fields, spread, .. } => {
799-
if let &Some(expr) = spread {
799+
if let &Spread::Base(expr) = spread {
800800
self.consume_expr(expr);
801801
}
802802
self.consume_exprs(fields.iter().map(|it| it.expr));

src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use either::Either;
1010
use hir_def::{
1111
hir::{
1212
ArithOp, Array, AsmOperand, AsmOptions, BinaryOp, ClosureKind, Expr, ExprId, ExprOrPatId,
13-
LabelId, Literal, Pat, PatId, Statement, UnaryOp,
13+
LabelId, Literal, Pat, PatId, Spread, Statement, UnaryOp,
1414
},
1515
lang_item::{LangItem, LangItemTarget},
1616
path::{GenericArg, GenericArgs, Path},
@@ -775,7 +775,7 @@ impl InferenceContext<'_> {
775775
}
776776
}
777777
}
778-
if let Some(expr) = spread {
778+
if let Spread::Base(expr) = spread {
779779
self.infer_expr(*expr, &Expectation::has_type(ty.clone()), ExprIsRead::Yes);
780780
}
781781
ty

src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
use chalk_ir::{cast::Cast, Mutability};
55
use hir_def::{
66
hir::{
7-
Array, AsmOperand, BinaryOp, BindingAnnotation, Expr, ExprId, Pat, PatId, Statement,
8-
UnaryOp,
7+
Array, AsmOperand, BinaryOp, BindingAnnotation, Expr, ExprId, Pat, PatId, Spread,
8+
Statement, UnaryOp,
99
},
1010
lang_item::LangItem,
1111
};
@@ -121,8 +121,12 @@ impl InferenceContext<'_> {
121121
Expr::Become { expr } => {
122122
self.infer_mut_expr(*expr, Mutability::Not);
123123
}
124-
Expr::RecordLit { path: _, fields, spread, ellipsis: _ } => {
125-
self.infer_mut_not_expr_iter(fields.iter().map(|it| it.expr).chain(*spread))
124+
Expr::RecordLit { path: _, fields, spread } => {
125+
let spread_expr = match spread {
126+
Spread::Base(expr) => Some(*expr),
127+
_ => None,
128+
};
129+
self.infer_mut_not_expr_iter(fields.iter().map(|it| it.expr).chain(spread_expr))
126130
}
127131
&Expr::Index { base, index } => {
128132
if mutability == Mutability::Mut {

src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use hir_def::{
99
expr_store::{Body, HygieneId},
1010
hir::{
1111
ArithOp, Array, BinaryOp, BindingAnnotation, BindingId, ExprId, LabelId, Literal,
12-
LiteralOrConst, MatchArm, Pat, PatId, RecordFieldPat, RecordLitField,
12+
LiteralOrConst, MatchArm, Pat, PatId, RecordFieldPat, RecordLitField, Spread,
1313
},
1414
lang_item::{LangItem, LangItemTarget},
1515
path::Path,
@@ -823,16 +823,16 @@ impl<'ctx> MirLowerCtx<'ctx> {
823823
}
824824
Expr::Become { .. } => not_supported!("tail-calls"),
825825
Expr::Yield { .. } => not_supported!("yield"),
826-
Expr::RecordLit { fields, path, spread, ellipsis: _ } => {
826+
Expr::RecordLit { fields, path, spread } => {
827827
let spread_place = match spread {
828-
&Some(it) => {
828+
&Spread::Base(it) => {
829829
let Some((p, c)) = self.lower_expr_as_place(current, it, true)? else {
830830
return Ok(None);
831831
};
832832
current = c;
833833
Some(p)
834834
}
835-
None => None,
835+
_ => None,
836836
};
837837
let variant_id =
838838
self.infer.variant_resolution_for_expr(expr_id).ok_or_else(|| match path {

src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1023,7 +1023,7 @@ impl SourceAnalyzer {
10231023
let expr_id = self.expr_id(db, &literal.clone().into())?;
10241024
let substs = infer[expr_id].as_adt()?.1;
10251025

1026-
let (variant, missing_fields, _exhaustive) = match expr_id {
1026+
let (variant, missing_fields, _) = match expr_id {
10271027
ExprOrPatId::ExprId(expr_id) => {
10281028
record_literal_missing_fields(db, infer, expr_id, &body[expr_id])?
10291029
}

0 commit comments

Comments
 (0)