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 @@ -559,6 +559,7 @@ fn expected_type_and_name<'db>(
559
559
token : & SyntaxToken ,
560
560
name_like : & ast:: NameLike ,
561
561
) -> ( Option < Type < ' db > > , Option < NameOrNameRef > ) {
562
+ let token = prev_assign_token_at_trivia ( token. clone ( ) ) ;
562
563
let mut node = match token. parent ( ) {
563
564
Some ( it) => it,
564
565
None => return ( None , None ) ,
@@ -629,6 +630,17 @@ fn expected_type_and_name<'db>(
629
630
. map( TypeInfo :: original) ;
630
631
( ty, None )
631
632
} ,
633
+ ast:: BinExpr ( it) => {
634
+ if let Some ( ast:: BinaryOp :: Assignment { op: None } ) = it. op_kind( ) {
635
+ let ty = it. lhs( )
636
+ . and_then( |lhs| sema. type_of_expr( & lhs) )
637
+ . or_else( || it. rhs( ) . and_then( |rhs| sema. type_of_expr( & rhs) ) )
638
+ . map( TypeInfo :: original) ;
639
+ ( ty, None )
640
+ } else {
641
+ ( None , None )
642
+ }
643
+ } ,
632
644
ast:: ArgList ( _) => {
633
645
cov_mark:: hit!( expected_type_fn_param) ;
634
646
ActiveParameter :: at_token(
@@ -1856,3 +1868,23 @@ fn next_non_trivia_sibling(ele: SyntaxElement) -> Option<SyntaxElement> {
1856
1868
}
1857
1869
None
1858
1870
}
1871
+
1872
+ fn prev_assign_token_at_trivia ( mut token : SyntaxToken ) -> SyntaxToken {
1873
+ while token. kind ( ) . is_trivia ( )
1874
+ && let Some ( prev) = token. prev_token ( )
1875
+ && let T ! [ =]
1876
+ | T ! [ +=]
1877
+ | T ! [ /=]
1878
+ | T ! [ *=]
1879
+ | T ! [ %=]
1880
+ | T ! [ >>=]
1881
+ | T ! [ <<=]
1882
+ | T ! [ -=]
1883
+ | T ! [ |=]
1884
+ | T ! [ &=]
1885
+ | T ! [ ^=] = prev. kind ( )
1886
+ {
1887
+ token = prev
1888
+ }
1889
+ token
1890
+ }
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