File tree Expand file tree Collapse file tree 2 files changed +82
-0
lines changed
crates/ide-completion/src/context Expand file tree Collapse file tree 2 files changed +82
-0
lines changed Original file line number Diff line number Diff line change @@ -562,6 +562,7 @@ fn expected_type_and_name<'db>(
562
562
token : & SyntaxToken ,
563
563
name_like : & ast:: NameLike ,
564
564
) -> ( Option < Type < ' db > > , Option < NameOrNameRef > ) {
565
+ let token = prev_assign_token_at_whitespace ( token. clone ( ) ) ;
565
566
let mut node = match token. parent ( ) {
566
567
Some ( it) => it,
567
568
None => return ( None , None ) ,
@@ -632,6 +633,17 @@ fn expected_type_and_name<'db>(
632
633
. map( TypeInfo :: original) ;
633
634
( ty, None )
634
635
} ,
636
+ ast:: BinExpr ( it) => {
637
+ if let Some ( ast:: BinaryOp :: Assignment { op: None } ) = it. op_kind( ) {
638
+ let ty = it. lhs( )
639
+ . and_then( |lhs| sema. type_of_expr( & lhs) )
640
+ . or_else( || it. rhs( ) . and_then( |rhs| sema. type_of_expr( & rhs) ) )
641
+ . map( TypeInfo :: original) ;
642
+ ( ty, None )
643
+ } else {
644
+ ( None , None )
645
+ }
646
+ } ,
635
647
ast:: ArgList ( _) => {
636
648
cov_mark:: hit!( expected_type_fn_param) ;
637
649
ActiveParameter :: at_token(
@@ -1870,3 +1882,23 @@ fn next_non_trivia_sibling(ele: SyntaxElement) -> Option<SyntaxElement> {
1870
1882
}
1871
1883
None
1872
1884
}
1885
+
1886
+ fn prev_assign_token_at_whitespace ( mut token : SyntaxToken ) -> SyntaxToken {
1887
+ while token. kind ( ) == SyntaxKind :: WHITESPACE
1888
+ && let Some ( prev) = token. prev_token ( )
1889
+ && let T ! [ =]
1890
+ | T ! [ +=]
1891
+ | T ! [ /=]
1892
+ | T ! [ *=]
1893
+ | T ! [ %=]
1894
+ | T ! [ >>=]
1895
+ | T ! [ <<=]
1896
+ | T ! [ -=]
1897
+ | T ! [ |=]
1898
+ | T ! [ &=]
1899
+ | T ! [ ^=] = prev. kind ( )
1900
+ {
1901
+ token = prev
1902
+ }
1903
+ token
1904
+ }
Original file line number Diff line number Diff line change @@ -434,3 +434,53 @@ fn f(thing: u32) -> &u32 {
434
434
expect ! [ "ty: u32, name: ?" ] ,
435
435
) ;
436
436
}
437
+
438
+ #[ test]
439
+ fn expected_type_assign ( ) {
440
+ check_expected_type_and_name (
441
+ r#"
442
+ enum State { Stop }
443
+ fn foo() {
444
+ let x: &mut State = &mut State::Stop;
445
+ x = $0;
446
+ }
447
+ "# ,
448
+ expect ! [ [ r#"ty: &'_ mut State, name: ?"# ] ] ,
449
+ ) ;
450
+ }
451
+
452
+ #[ test]
453
+ fn expected_type_deref_assign ( ) {
454
+ check_expected_type_and_name (
455
+ r#"
456
+ enum State { Stop }
457
+ fn foo() {
458
+ let x: &mut State = &mut State::Stop;
459
+ match x {
460
+ State::Stop => {
461
+ *x = $0;
462
+ },
463
+ }
464
+ }
465
+ "# ,
466
+ expect ! [ [ r#"ty: State, name: ?"# ] ] ,
467
+ ) ;
468
+ }
469
+
470
+ #[ test]
471
+ fn expected_type_deref_assign_at_block_end ( ) {
472
+ check_expected_type_and_name (
473
+ r#"
474
+ enum State { Stop }
475
+ fn foo() {
476
+ let x: &mut State = &mut State::Stop;
477
+ match x {
478
+ State::Stop => {
479
+ *x = $0
480
+ },
481
+ }
482
+ }
483
+ "# ,
484
+ expect ! [ [ r#"ty: State, name: ?"# ] ] ,
485
+ ) ;
486
+ }
You can’t perform that action at this time.
0 commit comments