Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/diagnostics/expr.rs')
| -rw-r--r-- | crates/hir-ty/src/diagnostics/expr.rs | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/crates/hir-ty/src/diagnostics/expr.rs b/crates/hir-ty/src/diagnostics/expr.rs index 0b5f131924..d744fe64c0 100644 --- a/crates/hir-ty/src/diagnostics/expr.rs +++ b/crates/hir-ty/src/diagnostics/expr.rs @@ -8,6 +8,7 @@ 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, @@ -546,9 +547,11 @@ pub fn record_literal_missing_fields( infer: &InferenceResult, id: ExprId, expr: &Expr, -) -> Option<(VariantId, Vec<LocalFieldId>, /*exhaustive*/ bool)> { - let (fields, exhaustive) = match expr { - Expr::RecordLit { fields, spread, .. } => (fields, spread.is_none()), +) -> Option<(VariantId, Vec<LocalFieldId>, /*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)) + } _ => return None, }; @@ -563,12 +566,18 @@ pub fn record_literal_missing_fields( let missed_fields: Vec<LocalFieldId> = variant_data .fields() .iter() - .filter_map(|(f, d)| if specified_fields.contains(&d.name) { None } else { Some(f) }) + .filter_map(|(f, d)| { + if (has_ellipsis && d.has_default) || specified_fields.contains(&d.name) { + None + } else { + Some(f) + } + }) .collect(); if missed_fields.is_empty() { return None; } - Some((variant_def, missed_fields, exhaustive)) + Some((variant_def, missed_fields, has_spread_expr)) } pub fn record_pattern_missing_fields( |