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>(
562562 token : & SyntaxToken ,
563563 name_like : & ast:: NameLike ,
564564) -> ( Option < Type < ' db > > , Option < NameOrNameRef > ) {
565+ let token = prev_assign_token_at_whitespace ( token. clone ( ) ) ;
565566 let mut node = match token. parent ( ) {
566567 Some ( it) => it,
567568 None => return ( None , None ) ,
@@ -632,6 +633,17 @@ fn expected_type_and_name<'db>(
632633 . map( TypeInfo :: original) ;
633634 ( ty, None )
634635 } ,
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+ } ,
635647 ast:: ArgList ( _) => {
636648 cov_mark:: hit!( expected_type_fn_param) ;
637649 ActiveParameter :: at_token(
@@ -1870,3 +1882,23 @@ fn next_non_trivia_sibling(ele: SyntaxElement) -> Option<SyntaxElement> {
18701882 }
18711883 None
18721884}
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 {
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