@@ -2,14 +2,18 @@ use std::collections::BTreeSet;
22
33use ast:: make;
44use either:: Either ;
5- use hir:: { db:: HirDatabase , sym, FileRange , PathResolution , Semantics , TypeInfo } ;
5+ use hir:: {
6+ db:: { ExpandDatabase , HirDatabase } ,
7+ sym, FileRange , PathResolution , Semantics , TypeInfo ,
8+ } ;
69use ide_db:: {
10+ base_db:: CrateId ,
711 defs:: Definition ,
812 imports:: insert_use:: remove_path_if_in_use_stmt,
913 path_transform:: PathTransform ,
1014 search:: { FileReference , FileReferenceNode , SearchScope } ,
1115 source_change:: SourceChangeBuilder ,
12- syntax_helpers:: { insert_whitespace_into_node :: insert_ws_into , node_ext:: expr_as_name_ref} ,
16+ syntax_helpers:: { node_ext:: expr_as_name_ref, prettify_macro_expansion } ,
1317 EditionedFileId , RootDatabase ,
1418} ;
1519use itertools:: { izip, Itertools } ;
@@ -102,12 +106,13 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) ->
102106 let mut remove_def = true ;
103107 let mut inline_refs_for_file = |file_id, refs : Vec < FileReference > | {
104108 builder. edit_file ( file_id) ;
109+ let call_krate = ctx. sema . file_to_module_def ( file_id) . map ( |it| it. krate ( ) ) ;
105110 let count = refs. len ( ) ;
106111 // The collects are required as we are otherwise iterating while mutating 🙅♀️🙅♂️
107112 let ( name_refs, name_refs_use) = split_refs_and_uses ( builder, refs, Some ) ;
108113 let call_infos: Vec < _ > = name_refs
109114 . into_iter ( )
110- . filter_map ( CallInfo :: from_name_ref)
115+ . filter_map ( |it| CallInfo :: from_name_ref ( it , call_krate? . into ( ) ) )
111116 // FIXME: do not handle callsites in macros' parameters, because
112117 // directly inlining into macros may cause errors.
113118 . filter ( |call_info| !ctx. sema . hir_file_for ( call_info. node . syntax ( ) ) . is_macro ( ) )
@@ -185,7 +190,10 @@ pub(super) fn split_refs_and_uses<T: ast::AstNode>(
185190// ```
186191pub ( crate ) fn inline_call ( acc : & mut Assists , ctx : & AssistContext < ' _ > ) -> Option < ( ) > {
187192 let name_ref: ast:: NameRef = ctx. find_node_at_offset ( ) ?;
188- let call_info = CallInfo :: from_name_ref ( name_ref. clone ( ) ) ?;
193+ let call_info = CallInfo :: from_name_ref (
194+ name_ref. clone ( ) ,
195+ ctx. sema . file_to_module_def ( ctx. file_id ( ) ) ?. krate ( ) . into ( ) ,
196+ ) ?;
189197 let ( function, label) = match & call_info. node {
190198 ast:: CallableExpr :: Call ( call) => {
191199 let path = match call. expr ( ) ? {
@@ -243,10 +251,11 @@ struct CallInfo {
243251 node : ast:: CallableExpr ,
244252 arguments : Vec < ast:: Expr > ,
245253 generic_arg_list : Option < ast:: GenericArgList > ,
254+ krate : CrateId ,
246255}
247256
248257impl CallInfo {
249- fn from_name_ref ( name_ref : ast:: NameRef ) -> Option < CallInfo > {
258+ fn from_name_ref ( name_ref : ast:: NameRef , krate : CrateId ) -> Option < CallInfo > {
250259 let parent = name_ref. syntax ( ) . parent ( ) ?;
251260 if let Some ( call) = ast:: MethodCallExpr :: cast ( parent. clone ( ) ) {
252261 let receiver = call. receiver ( ) ?;
@@ -256,6 +265,7 @@ impl CallInfo {
256265 generic_arg_list : call. generic_arg_list ( ) ,
257266 node : ast:: CallableExpr :: MethodCall ( call) ,
258267 arguments,
268+ krate,
259269 } )
260270 } else if let Some ( segment) = ast:: PathSegment :: cast ( parent) {
261271 let path = segment. syntax ( ) . parent ( ) . and_then ( ast:: Path :: cast) ?;
@@ -266,6 +276,7 @@ impl CallInfo {
266276 arguments : call. arg_list ( ) ?. args ( ) . collect ( ) ,
267277 node : ast:: CallableExpr :: Call ( call) ,
268278 generic_arg_list : segment. generic_arg_list ( ) ,
279+ krate,
269280 } )
270281 } else {
271282 None
@@ -307,11 +318,15 @@ fn inline(
307318 function : hir:: Function ,
308319 fn_body : & ast:: BlockExpr ,
309320 params : & [ ( ast:: Pat , Option < ast:: Type > , hir:: Param ) ] ,
310- CallInfo { node, arguments, generic_arg_list } : & CallInfo ,
321+ CallInfo { node, arguments, generic_arg_list, krate } : & CallInfo ,
311322) -> ast:: Expr {
312- let mut body = if sema. hir_file_for ( fn_body. syntax ( ) ) . is_macro ( ) {
323+ let file_id = sema. hir_file_for ( fn_body. syntax ( ) ) ;
324+ let mut body = if let Some ( macro_file) = file_id. macro_file ( ) {
313325 cov_mark:: hit!( inline_call_defined_in_macro) ;
314- if let Some ( body) = ast:: BlockExpr :: cast ( insert_ws_into ( fn_body. syntax ( ) . clone ( ) ) ) {
326+ let span_map = sema. db . expansion_span_map ( macro_file) ;
327+ let body_prettified =
328+ prettify_macro_expansion ( sema. db , fn_body. syntax ( ) . clone ( ) , & span_map, * krate) ;
329+ if let Some ( body) = ast:: BlockExpr :: cast ( body_prettified) {
315330 body
316331 } else {
317332 fn_body. clone_for_update ( )
@@ -420,8 +435,16 @@ fn inline(
420435
421436 let mut insert_let_stmt = || {
422437 let param_ty = param_ty. clone ( ) . map ( |param_ty| {
423- if sema. hir_file_for ( param_ty. syntax ( ) ) . is_macro ( ) {
424- ast:: Type :: cast ( insert_ws_into ( param_ty. syntax ( ) . clone ( ) ) ) . unwrap_or ( param_ty)
438+ let file_id = sema. hir_file_for ( param_ty. syntax ( ) ) ;
439+ if let Some ( macro_file) = file_id. macro_file ( ) {
440+ let span_map = sema. db . expansion_span_map ( macro_file) ;
441+ let param_ty_prettified = prettify_macro_expansion (
442+ sema. db ,
443+ param_ty. syntax ( ) . clone ( ) ,
444+ & span_map,
445+ * krate,
446+ ) ;
447+ ast:: Type :: cast ( param_ty_prettified) . unwrap_or ( param_ty)
425448 } else {
426449 param_ty
427450 }
0 commit comments