@@ -193,13 +193,21 @@ pub(crate) fn complete_postfix(
193193}
194194
195195fn 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 {
197197 let text = receiver. syntax ( ) . text ( ) ;
198198 let without_dot = ..text. len ( ) - TextSize :: of ( '.' ) ;
199199 text. slice ( without_dot) . to_string ( )
200200 } else {
201201 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 ( '$' , "\\ $" )
203211}
204212
205213fn include_references ( initial_element : & ast:: Expr ) -> ast:: Expr {
@@ -494,19 +502,21 @@ fn main() {
494502
495503 #[ test]
496504 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+
497518 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 ( ) ,
510520 "break" ,
511521 r#"
512522//- minicore: try
@@ -516,6 +526,44 @@ fn main() { 42.$0 }
516526use core::ops::ControlFlow;
517527
518528fn 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+ }
519567"# ,
520568 ) ;
521569 }
0 commit comments