diff --git a/crates/hir-def/src/expr_store.rs b/crates/hir-def/src/expr_store.rs index d0695d0eac..9df6eaade7 100644 --- a/crates/hir-def/src/expr_store.rs +++ b/crates/hir-def/src/expr_store.rs @@ -25,7 +25,7 @@ use crate::{ db::DefDatabase, hir::{ Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label, LabelId, Pat, - PatId, RecordFieldPat, Spread, Statement, + PatId, RecordFieldPat, Statement, }, nameres::DefMap, path::{ModPath, Path}, @@ -362,7 +362,7 @@ impl ExpressionStore { for field in fields.iter() { f(field.expr); } - if let &Spread::Base(expr) = spread { + if let &Some(expr) = spread { f(expr); } } @@ -490,7 +490,7 @@ impl ExpressionStore { for field in fields.iter() { f(field.expr); } - if let &Spread::Base(expr) = spread { + if let &Some(expr) = spread { f(expr); } } diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs index 811fecf91f..2cabd0f979 100644 --- a/crates/hir-def/src/expr_store/lower.rs +++ b/crates/hir-def/src/expr_store/lower.rs @@ -45,7 +45,7 @@ use crate::{ }, Array, Binding, BindingAnnotation, BindingId, BindingProblems, CaptureBy, ClosureKind, Expr, ExprId, Item, Label, LabelId, Literal, LiteralOrConst, MatchArm, Movability, - OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, Spread, Statement, + OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, Statement, }, item_scope::BuiltinShadowMode, lang_item::LangItem, @@ -602,13 +602,11 @@ impl ExprCollector<'_> { Some(RecordLitField { name, expr }) }) .collect(); - let spread = nfl.spread().map(|s| self.collect_expr(s)).map_or_else( - || if nfl.dotdot_token().is_some() { Spread::Yes } else { Spread::No }, - Spread::Base, - ); - Expr::RecordLit { path, fields, spread } + let spread = nfl.spread().map(|s| self.collect_expr(s)); + let ellipsis = nfl.dotdot_token().is_some(); + Expr::RecordLit { path, fields, spread, ellipsis } } else { - Expr::RecordLit { path, fields: Box::default(), spread: Spread::No } + Expr::RecordLit { path, fields: Box::default(), spread: None, ellipsis: false } }; self.alloc_expr(record_lit, syntax_ptr) diff --git a/crates/hir-def/src/expr_store/pretty.rs b/crates/hir-def/src/expr_store/pretty.rs index 1b3a1bb4dc..9a8a8c2cd0 100644 --- a/crates/hir-def/src/expr_store/pretty.rs +++ b/crates/hir-def/src/expr_store/pretty.rs @@ -8,7 +8,7 @@ use span::Edition; use crate::{ hir::{ Array, BindingAnnotation, CaptureBy, ClosureKind, Literal, LiteralOrConst, Movability, - Spread, Statement, + Statement, }, pretty::{print_generic_args, print_path, print_type_ref}, VariantId, @@ -398,7 +398,7 @@ impl Printer<'_> { self.print_expr(*expr); } } - Expr::RecordLit { path, fields, spread } => { + Expr::RecordLit { path, fields, spread, ellipsis: _ } => { match path { Some(path) => self.print_path(path), None => w!(self, "�"), @@ -412,16 +412,10 @@ impl Printer<'_> { p.print_expr(field.expr); wln!(p, ","); } - match spread { - Spread::No => {} - Spread::Yes => { - w!(p, ".."); - } - Spread::Base(expr) => { - w!(p, ".."); - p.print_expr(*expr); - wln!(p); - } + if let Some(spread) = spread { + w!(p, ".."); + p.print_expr(*spread); + wln!(p); } }); w!(self, "}}"); diff --git a/crates/hir-def/src/hir.rs b/crates/hir-def/src/hir.rs index e09ce67a89..1e2417ecdf 100644 --- a/crates/hir-def/src/hir.rs +++ b/crates/hir-def/src/hir.rs @@ -251,7 +251,8 @@ pub enum Expr { RecordLit { path: Option>, fields: Box<[RecordLitField]>, - spread: Spread, + spread: Option, + ellipsis: bool, }, Field { expr: ExprId, @@ -478,13 +479,6 @@ pub struct RecordLitField { pub expr: ExprId, } -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum Spread { - No, - Yes, - Base(ExprId), -} - #[derive(Debug, Clone, Eq, PartialEq)] pub enum Statement { Let { diff --git a/crates/hir-ty/src/diagnostics/expr.rs b/crates/hir-ty/src/diagnostics/expr.rs index dd55febbf0..d8700e2777 100644 --- a/crates/hir-ty/src/diagnostics/expr.rs +++ b/crates/hir-ty/src/diagnostics/expr.rs @@ -8,7 +8,6 @@ use base_db::CrateId; use chalk_solve::rust_ir::AdtKind; use either::Either; use hir_def::{ - hir::Spread, lang_item::LangItem, resolver::{HasResolver, ValueNs}, AdtId, AssocItemId, DefWithBodyId, HasModule, ItemContainerId, Lookup, @@ -547,11 +546,9 @@ pub fn record_literal_missing_fields( infer: &InferenceResult, id: ExprId, expr: &Expr, -) -> Option<(VariantId, Vec, /*has spread expr*/ bool)> { - let (fields, has_spread_expr, has_ellipsis) = match expr { - Expr::RecordLit { fields, spread, .. } => { - (fields, matches!(spread, Spread::Base(_)), matches!(spread, Spread::Yes)) - } +) -> Option<(VariantId, Vec, /*exhaustive*/ bool)> { + let (fields, exhaustive, ellipsis) = match expr { + Expr::RecordLit { fields, spread, ellipsis, .. } => (fields, spread.is_none(), *ellipsis), _ => return None, }; @@ -567,7 +564,7 @@ pub fn record_literal_missing_fields( .fields() .iter() .filter_map(|(f, d)| { - if (has_ellipsis && d.has_default) || specified_fields.contains(&d.name) { + if (ellipsis && d.has_default) || specified_fields.contains(&d.name) { None } else { Some(f) @@ -577,7 +574,7 @@ pub fn record_literal_missing_fields( if missed_fields.is_empty() { return None; } - Some((variant_def, missed_fields, has_spread_expr)) + Some((variant_def, missed_fields, exhaustive)) } pub fn record_pattern_missing_fields( diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs index 0e9aed4160..9283c46d0f 100644 --- a/crates/hir-ty/src/infer/closure.rs +++ b/crates/hir-ty/src/infer/closure.rs @@ -12,7 +12,7 @@ use hir_def::{ data::adt::VariantData, hir::{ Array, AsmOperand, BinaryOp, BindingId, CaptureBy, Expr, ExprId, ExprOrPatId, Pat, PatId, - Spread, Statement, UnaryOp, + Statement, UnaryOp, }, lang_item::LangItem, path::Path, @@ -796,7 +796,7 @@ impl InferenceContext<'_> { self.consume_expr(expr); } Expr::RecordLit { fields, spread, .. } => { - if let &Spread::Base(expr) = spread { + if let &Some(expr) = spread { self.consume_expr(expr); } self.consume_exprs(fields.iter().map(|it| it.expr)); diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index 8b3ec1ff2a..b951443897 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -10,7 +10,7 @@ use either::Either; use hir_def::{ hir::{ ArithOp, Array, AsmOperand, AsmOptions, BinaryOp, ClosureKind, Expr, ExprId, ExprOrPatId, - LabelId, Literal, Pat, PatId, Spread, Statement, UnaryOp, + LabelId, Literal, Pat, PatId, Statement, UnaryOp, }, lang_item::{LangItem, LangItemTarget}, path::{GenericArg, GenericArgs, Path}, @@ -775,7 +775,7 @@ impl InferenceContext<'_> { } } } - if let Spread::Base(expr) = spread { + if let Some(expr) = spread { self.infer_expr(*expr, &Expectation::has_type(ty.clone()), ExprIsRead::Yes); } ty diff --git a/crates/hir-ty/src/infer/mutability.rs b/crates/hir-ty/src/infer/mutability.rs index e95a425498..5b6c3cd152 100644 --- a/crates/hir-ty/src/infer/mutability.rs +++ b/crates/hir-ty/src/infer/mutability.rs @@ -4,8 +4,8 @@ use chalk_ir::{cast::Cast, Mutability}; use hir_def::{ hir::{ - Array, AsmOperand, BinaryOp, BindingAnnotation, Expr, ExprId, Pat, PatId, Spread, - Statement, UnaryOp, + Array, AsmOperand, BinaryOp, BindingAnnotation, Expr, ExprId, Pat, PatId, Statement, + UnaryOp, }, lang_item::LangItem, }; @@ -121,12 +121,8 @@ impl InferenceContext<'_> { Expr::Become { expr } => { self.infer_mut_expr(*expr, Mutability::Not); } - Expr::RecordLit { path: _, fields, spread } => { - let spread_expr = match spread { - Spread::Base(expr) => Some(*expr), - _ => None, - }; - self.infer_mut_not_expr_iter(fields.iter().map(|it| it.expr).chain(spread_expr)) + Expr::RecordLit { path: _, fields, spread, ellipsis: _ } => { + self.infer_mut_not_expr_iter(fields.iter().map(|it| it.expr).chain(*spread)) } &Expr::Index { base, index } => { if mutability == Mutability::Mut { diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index 5d89ebd4ef..85e8d17203 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -9,7 +9,7 @@ use hir_def::{ expr_store::{Body, HygieneId}, hir::{ ArithOp, Array, BinaryOp, BindingAnnotation, BindingId, ExprId, LabelId, Literal, - LiteralOrConst, MatchArm, Pat, PatId, RecordFieldPat, RecordLitField, Spread, + LiteralOrConst, MatchArm, Pat, PatId, RecordFieldPat, RecordLitField, }, lang_item::{LangItem, LangItemTarget}, path::Path, @@ -823,16 +823,16 @@ impl<'ctx> MirLowerCtx<'ctx> { } Expr::Become { .. } => not_supported!("tail-calls"), Expr::Yield { .. } => not_supported!("yield"), - Expr::RecordLit { fields, path, spread } => { + Expr::RecordLit { fields, path, spread, ellipsis: _ } => { let spread_place = match spread { - &Spread::Base(it) => { + &Some(it) => { let Some((p, c)) = self.lower_expr_as_place(current, it, true)? else { return Ok(None); }; current = c; Some(p) } - _ => None, + None => None, }; let variant_id = self.infer.variant_resolution_for_expr(expr_id).ok_or_else(|| match path { diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 98c30540b4..ca239826d4 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -1023,7 +1023,7 @@ impl SourceAnalyzer { let expr_id = self.expr_id(db, &literal.clone().into())?; let substs = infer[expr_id].as_adt()?.1; - let (variant, missing_fields, _) = match expr_id { + let (variant, missing_fields, _exhaustive) = match expr_id { ExprOrPatId::ExprId(expr_id) => { record_literal_missing_fields(db, infer, expr_id, &body[expr_id])? }