@@ -193,13 +193,21 @@ pub(crate) fn complete_postfix(
193
193
}
194
194
195
195
fn get_receiver_text ( receiver : & ast:: Expr , receiver_is_ambiguous_float_literal : bool ) -> String {
196
- if receiver_is_ambiguous_float_literal {
196
+ let text = if receiver_is_ambiguous_float_literal {
197
197
let text = receiver. syntax ( ) . text ( ) ;
198
198
let without_dot = ..text. len ( ) - TextSize :: of ( '.' ) ;
199
199
text. slice ( without_dot) . to_string ( )
200
200
} else {
201
201
receiver. to_string ( )
202
- }
202
+ } ;
203
+
204
+ // The receiver texts should be interpreted as-is, as they are expected to be
205
+ // normal Rust expressions. We escape '\' and '$' so they don't get treated as
206
+ // snippet-specific constructs.
207
+ //
208
+ // Note that we don't need to escape the other characters that can be escaped,
209
+ // because they wouldn't be treated as snippet-specific constructs without '$'.
210
+ text. replace ( '\\' , "\\ \\ " ) . replace ( '$' , "\\ $" )
203
211
}
204
212
205
213
fn include_references ( initial_element : & ast:: Expr ) -> ast:: Expr {
@@ -494,19 +502,21 @@ fn main() {
494
502
495
503
#[ test]
496
504
fn custom_postfix_completion ( ) {
505
+ let config = CompletionConfig {
506
+ snippets : vec ! [ Snippet :: new(
507
+ & [ ] ,
508
+ & [ "break" . into( ) ] ,
509
+ & [ "ControlFlow::Break(${receiver})" . into( ) ] ,
510
+ "" ,
511
+ & [ "core::ops::ControlFlow" . into( ) ] ,
512
+ crate :: SnippetScope :: Expr ,
513
+ )
514
+ . unwrap( ) ] ,
515
+ ..TEST_CONFIG
516
+ } ;
517
+
497
518
check_edit_with_config (
498
- CompletionConfig {
499
- snippets : vec ! [ Snippet :: new(
500
- & [ ] ,
501
- & [ "break" . into( ) ] ,
502
- & [ "ControlFlow::Break(${receiver})" . into( ) ] ,
503
- "" ,
504
- & [ "core::ops::ControlFlow" . into( ) ] ,
505
- crate :: SnippetScope :: Expr ,
506
- )
507
- . unwrap( ) ] ,
508
- ..TEST_CONFIG
509
- } ,
519
+ config. clone ( ) ,
510
520
"break" ,
511
521
r#"
512
522
//- minicore: try
@@ -516,6 +526,44 @@ fn main() { 42.$0 }
516
526
use core::ops::ControlFlow;
517
527
518
528
fn main() { ControlFlow::Break(42) }
529
+ "# ,
530
+ ) ;
531
+
532
+ check_edit_with_config (
533
+ config. clone ( ) ,
534
+ "break" ,
535
+ r#"
536
+ //- minicore: try
537
+ fn main() { '\\'.$0 }
538
+ "# ,
539
+ r#"
540
+ use core::ops::ControlFlow;
541
+
542
+ fn main() { ControlFlow::Break('\\\\') }
543
+ "# ,
544
+ ) ;
545
+
546
+ check_edit_with_config (
547
+ config. clone ( ) ,
548
+ "break" ,
549
+ r#"
550
+ //- minicore: try
551
+ fn main() {
552
+ match true {
553
+ true => "${1:placeholder}",
554
+ false => "\$",
555
+ }.$0
556
+ }
557
+ "# ,
558
+ r#"
559
+ use core::ops::ControlFlow;
560
+
561
+ fn main() {
562
+ ControlFlow::Break(match true {
563
+ true => "\${1:placeholder}",
564
+ false => "\\\$",
565
+ })
566
+ }
519
567
"# ,
520
568
) ;
521
569
}
0 commit comments