File tree Expand file tree Collapse file tree 2 files changed +193
-0
lines changed
src/tools/rust-analyzer/crates/ide-completion/src Expand file tree Collapse file tree 2 files changed +193
-0
lines changed Original file line number Diff line number Diff line change @@ -1890,11 +1890,37 @@ fn is_in_breakable(node: &SyntaxNode) -> Option<(BreakableKind, SyntaxNode)> {
18901890}
18911891
18921892fn is_in_block ( node : & SyntaxNode ) -> bool {
1893+ if has_in_newline_expr_first ( node) {
1894+ return true ;
1895+ } ;
18931896 node. parent ( )
18941897 . map ( |node| ast:: ExprStmt :: can_cast ( node. kind ( ) ) || ast:: StmtList :: can_cast ( node. kind ( ) ) )
18951898 . unwrap_or ( false )
18961899}
18971900
1901+ /// Similar to `has_parens`, heuristic sensing incomplete statement before ambigiguous `Expr`
1902+ ///
1903+ /// Heuristic:
1904+ ///
1905+ /// If the `PathExpr` is left part of the `Expr` and there is a newline after the `PathExpr`,
1906+ /// it is considered that the `PathExpr` is not part of the `Expr`.
1907+ fn has_in_newline_expr_first ( node : & SyntaxNode ) -> bool {
1908+ if ast:: PathExpr :: can_cast ( node. kind ( ) )
1909+ && let Some ( NodeOrToken :: Token ( next) ) = node. next_sibling_or_token ( )
1910+ && next. kind ( ) == SyntaxKind :: WHITESPACE
1911+ && next. text ( ) . contains ( '\n' )
1912+ && let Some ( stmt_like) = node
1913+ . ancestors ( )
1914+ . take_while ( |it| it. text_range ( ) . start ( ) == node. text_range ( ) . start ( ) )
1915+ . filter_map ( Either :: < ast:: ExprStmt , ast:: Expr > :: cast)
1916+ . last ( )
1917+ {
1918+ stmt_like. syntax ( ) . parent ( ) . and_then ( ast:: StmtList :: cast) . is_some ( )
1919+ } else {
1920+ false
1921+ }
1922+ }
1923+
18981924fn next_non_trivia_token ( e : impl Into < SyntaxElement > ) -> Option < SyntaxToken > {
18991925 let mut token = match e. into ( ) {
19001926 SyntaxElement :: Node ( n) => n. last_token ( ) ?,
Original file line number Diff line number Diff line change @@ -2946,6 +2946,173 @@ fn let_in_let_chain() {
29462946 check_edit ( "let" , r#"fn f() { if true && $0 {} }"# , r#"fn f() { if true && let $1 = $0 {} }"# ) ;
29472947}
29482948
2949+ #[ test]
2950+ fn let_in_previous_line_of_ambiguous_expr ( ) {
2951+ check_edit (
2952+ "let" ,
2953+ r#"
2954+ fn f() {
2955+ $0
2956+ (1, 2).foo();
2957+ }"# ,
2958+ r#"
2959+ fn f() {
2960+ let $1 = $0;
2961+ (1, 2).foo();
2962+ }"# ,
2963+ ) ;
2964+
2965+ check_edit (
2966+ "let" ,
2967+ r#"
2968+ fn f() {
2969+ $0
2970+ (1, 2)
2971+ }"# ,
2972+ r#"
2973+ fn f() {
2974+ let $1 = $0;
2975+ (1, 2)
2976+ }"# ,
2977+ ) ;
2978+
2979+ check_edit (
2980+ "let" ,
2981+ r#"
2982+ fn f() -> i32 {
2983+ $0
2984+ -2
2985+ }"# ,
2986+ r#"
2987+ fn f() -> i32 {
2988+ let $1 = $0;
2989+ -2
2990+ }"# ,
2991+ ) ;
2992+
2993+ check_edit (
2994+ "let" ,
2995+ r#"
2996+ fn f() -> [i32; 2] {
2997+ $0
2998+ [1, 2]
2999+ }"# ,
3000+ r#"
3001+ fn f() -> [i32; 2] {
3002+ let $1 = $0;
3003+ [1, 2]
3004+ }"# ,
3005+ ) ;
3006+
3007+ check_edit (
3008+ "let" ,
3009+ r#"
3010+ fn f() -> [u8; 2] {
3011+ $0
3012+ *b"01"
3013+ }"# ,
3014+ r#"
3015+ fn f() -> [u8; 2] {
3016+ let $1 = $0;
3017+ *b"01"
3018+ }"# ,
3019+ ) ;
3020+
3021+ check (
3022+ r#"
3023+ fn foo() {
3024+ $0
3025+ *b"01"
3026+ }"# ,
3027+ expect ! [ [ r#"
3028+ fn foo() fn()
3029+ bt u32 u32
3030+ kw async
3031+ kw const
3032+ kw crate::
3033+ kw enum
3034+ kw extern
3035+ kw false
3036+ kw fn
3037+ kw for
3038+ kw if
3039+ kw if let
3040+ kw impl
3041+ kw impl for
3042+ kw let
3043+ kw letm
3044+ kw loop
3045+ kw match
3046+ kw mod
3047+ kw return
3048+ kw self::
3049+ kw static
3050+ kw struct
3051+ kw trait
3052+ kw true
3053+ kw type
3054+ kw union
3055+ kw unsafe
3056+ kw use
3057+ kw while
3058+ kw while let
3059+ sn macro_rules
3060+ sn pd
3061+ sn ppd
3062+ "# ] ] ,
3063+ ) ;
3064+
3065+ check (
3066+ r#"
3067+ fn foo() {
3068+ match $0 {}
3069+ }"# ,
3070+ expect ! [ [ r#"
3071+ fn foo() fn()
3072+ bt u32 u32
3073+ kw const
3074+ kw crate::
3075+ kw false
3076+ kw for
3077+ kw if
3078+ kw if let
3079+ kw loop
3080+ kw match
3081+ kw return
3082+ kw self::
3083+ kw true
3084+ kw unsafe
3085+ kw while
3086+ kw while let
3087+ "# ] ] ,
3088+ ) ;
3089+
3090+ check (
3091+ r#"
3092+ fn foo() {
3093+ $0 *b"01"
3094+ }"# ,
3095+ expect ! [ [ r#"
3096+ fn foo() fn()
3097+ bt u32 u32
3098+ kw const
3099+ kw crate::
3100+ kw false
3101+ kw for
3102+ kw if
3103+ kw if let
3104+ kw loop
3105+ kw match
3106+ kw return
3107+ kw self::
3108+ kw true
3109+ kw unsafe
3110+ kw while
3111+ kw while let
3112+ "# ] ] ,
3113+ ) ;
3114+ }
3115+
29493116#[ test]
29503117fn private_inherent_and_public_trait ( ) {
29513118 check (
You can’t perform that action at this time.
0 commit comments