@@ -85,11 +85,12 @@ pub(crate) fn inline_(
8585 make:: name ( "this" ) ,
8686 )
8787 . into ( ) ,
88+ None ,
8889 assoc_fn_params. next ( ) ?,
8990 ) ) ;
9091 }
9192 for param in param_list. params ( ) {
92- params. push ( ( param. pat ( ) ?, assoc_fn_params. next ( ) ?) ) ;
93+ params. push ( ( param. pat ( ) ?, param . ty ( ) , assoc_fn_params. next ( ) ?) ) ;
9394 }
9495
9596 if arg_list. len ( ) != params. len ( ) {
@@ -123,7 +124,7 @@ pub(crate) fn inline_(
123124 // has a pattern that does not allow inlining
124125 let param_use_nodes: Vec < Vec < _ > > = params
125126 . iter ( )
126- . map ( |( pat, param) | {
127+ . map ( |( pat, _ , param) | {
127128 if !matches ! ( pat, ast:: Pat :: IdentPat ( pat) if pat. is_simple_ident( ) ) {
128129 return Vec :: new ( ) ;
129130 }
@@ -145,7 +146,7 @@ pub(crate) fn inline_(
145146 // Rewrite `self` to `this`
146147 if param_list. self_param ( ) . is_some ( ) {
147148 let this = || make:: name_ref ( "this" ) . syntax ( ) . clone_for_update ( ) ;
148- usages_for_locals ( params[ 0 ] . 1 . as_local ( ctx. sema . db ) )
149+ usages_for_locals ( params[ 0 ] . 2 . as_local ( ctx. sema . db ) )
149150 . flat_map ( |FileReference { name, range, .. } | match name {
150151 ast:: NameLike :: NameRef ( _) => Some ( body. syntax ( ) . covering_element ( range) ) ,
151152 _ => None ,
@@ -156,7 +157,8 @@ pub(crate) fn inline_(
156157 }
157158
158159 // Inline parameter expressions or generate `let` statements depending on whether inlining works or not.
159- for ( ( pat, _) , usages, expr) in izip ! ( params, param_use_nodes, arg_list) . rev ( ) {
160+ for ( ( pat, param_ty, _) , usages, expr) in izip ! ( params, param_use_nodes, arg_list) . rev ( )
161+ {
160162 let expr_is_name_ref = matches ! ( & expr,
161163 ast:: Expr :: PathExpr ( expr)
162164 if expr. path( ) . and_then( |path| path. as_single_name_ref( ) ) . is_some( )
@@ -184,8 +186,17 @@ pub(crate) fn inline_(
184186 } ) ;
185187 }
186188 // cant inline, emit a let statement
187- // FIXME: emit type ascriptions when a coercion happens?
188- _ => body. push_front ( make:: let_stmt ( pat, Some ( expr) ) . clone_for_update ( ) . into ( ) ) ,
189+ _ => {
190+ let ty = ctx
191+ . sema
192+ . type_of_expr_with_coercion ( & expr)
193+ . map_or ( false , |( _, coerced) | coerced. is_some ( ) )
194+ . then ( || param_ty)
195+ . flatten ( ) ;
196+ body. push_front (
197+ make:: let_stmt ( pat, ty, Some ( expr) ) . clone_for_update ( ) . into ( ) ,
198+ )
199+ }
189200 }
190201 }
191202
@@ -606,6 +617,34 @@ fn foo(x: u32) -> u32{
606617fn main() {
607618 222;
608619}
620+ "# ,
621+ ) ;
622+ }
623+
624+ #[ test]
625+ fn inline_emits_type_for_coercion ( ) {
626+ check_assist (
627+ inline_call,
628+ r#"
629+ fn foo(x: *const u32) -> u32 {
630+ x as u32
631+ }
632+
633+ fn main() {
634+ foo$0(&222);
635+ }
636+ "# ,
637+ r#"
638+ fn foo(x: *const u32) -> u32 {
639+ x as u32
640+ }
641+
642+ fn main() {
643+ {
644+ let x: *const u32 = &222;
645+ x as u32
646+ };
647+ }
609648"# ,
610649 ) ;
611650 }
0 commit comments