|
1 | 1 | //! Completion of names from the current scope in expression position.
|
2 | 2 |
|
3 | 3 | use hir::ScopeDef;
|
| 4 | +use syntax::ast; |
4 | 5 |
|
5 | 6 | use crate::{
|
| 7 | + completions::record::add_default_update, |
6 | 8 | context::{ExprCtx, PathCompletionCtx, Qualified},
|
7 | 9 | CompletionContext, Completions,
|
8 | 10 | };
|
@@ -219,60 +221,78 @@ pub(crate) fn complete_expr_path(
|
219 | 221 | _ => (),
|
220 | 222 | });
|
221 | 223 |
|
222 |
| - if is_func_update.is_none() { |
223 |
| - let mut add_keyword = |
224 |
| - |kw, snippet| acc.add_keyword_snippet_expr(ctx, incomplete_let, kw, snippet); |
| 224 | + match is_func_update { |
| 225 | + Some(record_expr) => { |
| 226 | + let ty = ctx.sema.type_of_expr(&ast::Expr::RecordExpr(record_expr.clone())); |
225 | 227 |
|
226 |
| - if !in_block_expr { |
227 |
| - add_keyword("unsafe", "unsafe {\n $0\n}"); |
228 |
| - } |
229 |
| - add_keyword("match", "match $1 {\n $0\n}"); |
230 |
| - add_keyword("while", "while $1 {\n $0\n}"); |
231 |
| - add_keyword("while let", "while let $1 = $2 {\n $0\n}"); |
232 |
| - add_keyword("loop", "loop {\n $0\n}"); |
233 |
| - if in_match_guard { |
234 |
| - add_keyword("if", "if $0"); |
235 |
| - } else { |
236 |
| - add_keyword("if", "if $1 {\n $0\n}"); |
| 228 | + match ty.as_ref().and_then(|t| t.original.as_adt()) { |
| 229 | + Some(hir::Adt::Union(_)) => (), |
| 230 | + _ => { |
| 231 | + cov_mark::hit!(functional_update); |
| 232 | + let missing_fields = |
| 233 | + ctx.sema.record_literal_missing_fields(record_expr); |
| 234 | + if !missing_fields.is_empty() { |
| 235 | + add_default_update(acc, ctx, ty); |
| 236 | + } |
| 237 | + } |
| 238 | + }; |
237 | 239 | }
|
238 |
| - add_keyword("if let", "if let $1 = $2 {\n $0\n}"); |
239 |
| - add_keyword("for", "for $1 in $2 {\n $0\n}"); |
240 |
| - add_keyword("true", "true"); |
241 |
| - add_keyword("false", "false"); |
| 240 | + None => { |
| 241 | + let mut add_keyword = |kw, snippet| { |
| 242 | + acc.add_keyword_snippet_expr(ctx, incomplete_let, kw, snippet) |
| 243 | + }; |
242 | 244 |
|
243 |
| - if in_condition || in_block_expr { |
244 |
| - add_keyword("let", "let"); |
245 |
| - } |
| 245 | + if !in_block_expr { |
| 246 | + add_keyword("unsafe", "unsafe {\n $0\n}"); |
| 247 | + } |
| 248 | + add_keyword("match", "match $1 {\n $0\n}"); |
| 249 | + add_keyword("while", "while $1 {\n $0\n}"); |
| 250 | + add_keyword("while let", "while let $1 = $2 {\n $0\n}"); |
| 251 | + add_keyword("loop", "loop {\n $0\n}"); |
| 252 | + if in_match_guard { |
| 253 | + add_keyword("if", "if $0"); |
| 254 | + } else { |
| 255 | + add_keyword("if", "if $1 {\n $0\n}"); |
| 256 | + } |
| 257 | + add_keyword("if let", "if let $1 = $2 {\n $0\n}"); |
| 258 | + add_keyword("for", "for $1 in $2 {\n $0\n}"); |
| 259 | + add_keyword("true", "true"); |
| 260 | + add_keyword("false", "false"); |
246 | 261 |
|
247 |
| - if after_if_expr { |
248 |
| - add_keyword("else", "else {\n $0\n}"); |
249 |
| - add_keyword("else if", "else if $1 {\n $0\n}"); |
250 |
| - } |
| 262 | + if in_condition || in_block_expr { |
| 263 | + add_keyword("let", "let"); |
| 264 | + } |
251 | 265 |
|
252 |
| - if wants_mut_token { |
253 |
| - add_keyword("mut", "mut "); |
254 |
| - } |
| 266 | + if after_if_expr { |
| 267 | + add_keyword("else", "else {\n $0\n}"); |
| 268 | + add_keyword("else if", "else if $1 {\n $0\n}"); |
| 269 | + } |
255 | 270 |
|
256 |
| - if in_loop_body { |
257 |
| - if in_block_expr { |
258 |
| - add_keyword("continue", "continue;"); |
259 |
| - add_keyword("break", "break;"); |
260 |
| - } else { |
261 |
| - add_keyword("continue", "continue"); |
262 |
| - add_keyword("break", "break"); |
| 271 | + if wants_mut_token { |
| 272 | + add_keyword("mut", "mut "); |
| 273 | + } |
| 274 | + |
| 275 | + if in_loop_body { |
| 276 | + if in_block_expr { |
| 277 | + add_keyword("continue", "continue;"); |
| 278 | + add_keyword("break", "break;"); |
| 279 | + } else { |
| 280 | + add_keyword("continue", "continue"); |
| 281 | + add_keyword("break", "break"); |
| 282 | + } |
263 | 283 | }
|
264 |
| - } |
265 | 284 |
|
266 |
| - if let Some(ty) = innermost_ret_ty { |
267 |
| - add_keyword( |
268 |
| - "return", |
269 |
| - match (in_block_expr, ty.is_unit()) { |
270 |
| - (true, true) => "return ;", |
271 |
| - (true, false) => "return;", |
272 |
| - (false, true) => "return $0", |
273 |
| - (false, false) => "return", |
274 |
| - }, |
275 |
| - ); |
| 285 | + if let Some(ty) = innermost_ret_ty { |
| 286 | + add_keyword( |
| 287 | + "return", |
| 288 | + match (in_block_expr, ty.is_unit()) { |
| 289 | + (true, true) => "return ;", |
| 290 | + (true, false) => "return;", |
| 291 | + (false, true) => "return $0", |
| 292 | + (false, false) => "return", |
| 293 | + }, |
| 294 | + ); |
| 295 | + } |
276 | 296 | }
|
277 | 297 | }
|
278 | 298 | }
|
|
0 commit comments