Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/inline_call.rs')
-rw-r--r--crates/ide-assists/src/handlers/inline_call.rs44
1 files changed, 34 insertions, 10 deletions
diff --git a/crates/ide-assists/src/handlers/inline_call.rs b/crates/ide-assists/src/handlers/inline_call.rs
index 5bd204dd57..9e09f198fe 100644
--- a/crates/ide-assists/src/handlers/inline_call.rs
+++ b/crates/ide-assists/src/handlers/inline_call.rs
@@ -2,14 +2,18 @@ use std::collections::BTreeSet;
use ast::make;
use either::Either;
-use hir::{db::HirDatabase, sym, FileRange, PathResolution, Semantics, TypeInfo};
+use hir::{
+ db::{ExpandDatabase, HirDatabase},
+ sym, FileRange, PathResolution, Semantics, TypeInfo,
+};
use ide_db::{
+ base_db::CrateId,
defs::Definition,
imports::insert_use::remove_path_if_in_use_stmt,
path_transform::PathTransform,
search::{FileReference, FileReferenceNode, SearchScope},
source_change::SourceChangeBuilder,
- syntax_helpers::{insert_whitespace_into_node::insert_ws_into, node_ext::expr_as_name_ref},
+ syntax_helpers::{node_ext::expr_as_name_ref, prettify_macro_expansion},
EditionedFileId, RootDatabase,
};
use itertools::{izip, Itertools};
@@ -102,12 +106,13 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) ->
let mut remove_def = true;
let mut inline_refs_for_file = |file_id, refs: Vec<FileReference>| {
builder.edit_file(file_id);
+ let call_krate = ctx.sema.file_to_module_def(file_id).map(|it| it.krate());
let count = refs.len();
// The collects are required as we are otherwise iterating while mutating 🙅‍♀️🙅‍♂️
let (name_refs, name_refs_use) = split_refs_and_uses(builder, refs, Some);
let call_infos: Vec<_> = name_refs
.into_iter()
- .filter_map(CallInfo::from_name_ref)
+ .filter_map(|it| CallInfo::from_name_ref(it, call_krate?.into()))
// FIXME: do not handle callsites in macros' parameters, because
// directly inlining into macros may cause errors.
.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>(
// ```
pub(crate) fn inline_call(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
let name_ref: ast::NameRef = ctx.find_node_at_offset()?;
- let call_info = CallInfo::from_name_ref(name_ref.clone())?;
+ let call_info = CallInfo::from_name_ref(
+ name_ref.clone(),
+ ctx.sema.file_to_module_def(ctx.file_id())?.krate().into(),
+ )?;
let (function, label) = match &call_info.node {
ast::CallableExpr::Call(call) => {
let path = match call.expr()? {
@@ -243,10 +251,11 @@ struct CallInfo {
node: ast::CallableExpr,
arguments: Vec<ast::Expr>,
generic_arg_list: Option<ast::GenericArgList>,
+ krate: CrateId,
}
impl CallInfo {
- fn from_name_ref(name_ref: ast::NameRef) -> Option<CallInfo> {
+ fn from_name_ref(name_ref: ast::NameRef, krate: CrateId) -> Option<CallInfo> {
let parent = name_ref.syntax().parent()?;
if let Some(call) = ast::MethodCallExpr::cast(parent.clone()) {
let receiver = call.receiver()?;
@@ -256,6 +265,7 @@ impl CallInfo {
generic_arg_list: call.generic_arg_list(),
node: ast::CallableExpr::MethodCall(call),
arguments,
+ krate,
})
} else if let Some(segment) = ast::PathSegment::cast(parent) {
let path = segment.syntax().parent().and_then(ast::Path::cast)?;
@@ -266,6 +276,7 @@ impl CallInfo {
arguments: call.arg_list()?.args().collect(),
node: ast::CallableExpr::Call(call),
generic_arg_list: segment.generic_arg_list(),
+ krate,
})
} else {
None
@@ -307,11 +318,15 @@ fn inline(
function: hir::Function,
fn_body: &ast::BlockExpr,
params: &[(ast::Pat, Option<ast::Type>, hir::Param)],
- CallInfo { node, arguments, generic_arg_list }: &CallInfo,
+ CallInfo { node, arguments, generic_arg_list, krate }: &CallInfo,
) -> ast::Expr {
- let mut body = if sema.hir_file_for(fn_body.syntax()).is_macro() {
+ let file_id = sema.hir_file_for(fn_body.syntax());
+ let mut body = if let Some(macro_file) = file_id.macro_file() {
cov_mark::hit!(inline_call_defined_in_macro);
- if let Some(body) = ast::BlockExpr::cast(insert_ws_into(fn_body.syntax().clone())) {
+ let span_map = sema.db.expansion_span_map(macro_file);
+ let body_prettified =
+ prettify_macro_expansion(sema.db, fn_body.syntax().clone(), &span_map, *krate);
+ if let Some(body) = ast::BlockExpr::cast(body_prettified) {
body
} else {
fn_body.clone_for_update()
@@ -420,8 +435,16 @@ fn inline(
let mut insert_let_stmt = || {
let param_ty = param_ty.clone().map(|param_ty| {
- if sema.hir_file_for(param_ty.syntax()).is_macro() {
- ast::Type::cast(insert_ws_into(param_ty.syntax().clone())).unwrap_or(param_ty)
+ let file_id = sema.hir_file_for(param_ty.syntax());
+ if let Some(macro_file) = file_id.macro_file() {
+ let span_map = sema.db.expansion_span_map(macro_file);
+ let param_ty_prettified = prettify_macro_expansion(
+ sema.db,
+ param_ty.syntax().clone(),
+ &span_map,
+ *krate,
+ );
+ ast::Type::cast(param_ty_prettified).unwrap_or(param_ty)
} else {
param_ty
}
@@ -1020,6 +1043,7 @@ fn main() {
check_assist(
inline_call,
r#"
+//- minicore: sized
fn foo(x: *const u32) -> u32 {
x as u32
}