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>(
559559 token : & SyntaxToken ,
560560 name_like : & ast:: NameLike ,
561561) -> ( Option < Type < ' db > > , Option < NameOrNameRef > ) {
562+ let token = prev_assign_token_at_trivia ( token. clone ( ) ) ;
562563 let mut node = match token. parent ( ) {
563564 Some ( it) => it,
564565 None => return ( None , None ) ,
@@ -629,6 +630,17 @@ fn expected_type_and_name<'db>(
629630 . map( TypeInfo :: original) ;
630631 ( ty, None )
631632 } ,
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+ } ,
632644 ast:: ArgList ( _) => {
633645 cov_mark:: hit!( expected_type_fn_param) ;
634646 ActiveParameter :: at_token(
@@ -1856,3 +1868,23 @@ fn next_non_trivia_sibling(ele: SyntaxElement) -> Option<SyntaxElement> {
18561868 }
18571869 None
18581870}
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 {
434434 expect ! [ "ty: u32, name: ?" ] ,
435435 ) ;
436436}
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