Unnamed repository; edit this file 'description' to name the repository.
Use `display_source_code()` in `ReferenceConversion`
The usage of normal `display()` caused it to emit `{unknown}` which then failed to parse in `make::ty()`. Really we should not use stringly-typed things here, but that's a change for another day.
Chayim Refael Friedman 3 months ago
parent 74eca73 · commit d46ab4f
-rw-r--r--crates/ide-assists/src/handlers/generate_function.rs31
-rw-r--r--crates/ide-assists/src/handlers/generate_getter_or_setter.rs6
-rw-r--r--crates/ide-assists/src/utils.rs40
3 files changed, 48 insertions, 29 deletions
diff --git a/crates/ide-assists/src/handlers/generate_function.rs b/crates/ide-assists/src/handlers/generate_function.rs
index bd66c02b41..ded3b0f5ac 100644
--- a/crates/ide-assists/src/handlers/generate_function.rs
+++ b/crates/ide-assists/src/handlers/generate_function.rs
@@ -1147,14 +1147,7 @@ fn fn_arg_type(
if ty.is_reference() || ty.is_mutable_reference() {
let famous_defs = &FamousDefs(&ctx.sema, ctx.sema.scope(fn_arg.syntax())?.krate());
convert_reference_type(ty.strip_references(), ctx.db(), famous_defs)
- .map(|conversion| {
- conversion
- .convert_type(
- ctx.db(),
- target_module.krate(ctx.db()).to_display_target(ctx.db()),
- )
- .to_string()
- })
+ .map(|conversion| conversion.convert_type(ctx.db(), target_module).to_string())
.or_else(|| ty.display_source_code(ctx.db(), target_module.into(), true).ok())
} else {
ty.display_source_code(ctx.db(), target_module.into(), true).ok()
@@ -3191,4 +3184,26 @@ fn main() {
"#,
);
}
+
+ #[test]
+ fn regression_21288() {
+ check_assist(
+ generate_function,
+ r#"
+//- minicore: copy
+fn foo() {
+ $0bar(&|x| true)
+}
+ "#,
+ r#"
+fn foo() {
+ bar(&|x| true)
+}
+
+fn bar(arg: impl Fn(_) -> bool) {
+ ${0:todo!()}
+}
+ "#,
+ );
+ }
}
diff --git a/crates/ide-assists/src/handlers/generate_getter_or_setter.rs b/crates/ide-assists/src/handlers/generate_getter_or_setter.rs
index e42d0ed1b0..73e93a3fbf 100644
--- a/crates/ide-assists/src/handlers/generate_getter_or_setter.rs
+++ b/crates/ide-assists/src/handlers/generate_getter_or_setter.rs
@@ -226,15 +226,15 @@ fn generate_getter_from_info(
)
} else {
(|| {
- let krate = ctx.sema.scope(record_field_info.field_ty.syntax())?.krate();
- let famous_defs = &FamousDefs(&ctx.sema, krate);
+ let module = ctx.sema.scope(record_field_info.field_ty.syntax())?.module();
+ let famous_defs = &FamousDefs(&ctx.sema, module.krate(ctx.db()));
ctx.sema
.resolve_type(&record_field_info.field_ty)
.and_then(|ty| convert_reference_type(ty, ctx.db(), famous_defs))
.map(|conversion| {
cov_mark::hit!(convert_reference_type);
(
- conversion.convert_type(ctx.db(), krate.to_display_target(ctx.db())),
+ conversion.convert_type(ctx.db(), module),
conversion.getter(record_field_info.field_name.to_string()),
)
})
diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs
index 4b8c193057..5e08cba8e2 100644
--- a/crates/ide-assists/src/utils.rs
+++ b/crates/ide-assists/src/utils.rs
@@ -4,8 +4,7 @@ use std::slice;
pub(crate) use gen_trait_fn_body::gen_trait_fn_body;
use hir::{
- DisplayTarget, HasAttrs as HirHasAttrs, HirDisplay, InFile, ModuleDef, PathResolution,
- Semantics,
+ HasAttrs as HirHasAttrs, HirDisplay, InFile, ModuleDef, PathResolution, Semantics,
db::{ExpandDatabase, HirDatabase},
};
use ide_db::{
@@ -836,13 +835,12 @@ enum ReferenceConversionType {
}
impl<'db> ReferenceConversion<'db> {
- pub(crate) fn convert_type(
- &self,
- db: &'db dyn HirDatabase,
- display_target: DisplayTarget,
- ) -> ast::Type {
+ pub(crate) fn convert_type(&self, db: &'db dyn HirDatabase, module: hir::Module) -> ast::Type {
let ty = match self.conversion {
- ReferenceConversionType::Copy => self.ty.display(db, display_target).to_string(),
+ ReferenceConversionType::Copy => self
+ .ty
+ .display_source_code(db, module.into(), true)
+ .unwrap_or_else(|_| "_".to_owned()),
ReferenceConversionType::AsRefStr => "&str".to_owned(),
ReferenceConversionType::AsRefSlice => {
let type_argument_name = self
@@ -850,8 +848,8 @@ impl<'db> ReferenceConversion<'db> {
.type_arguments()
.next()
.unwrap()
- .display(db, display_target)
- .to_string();
+ .display_source_code(db, module.into(), true)
+ .unwrap_or_else(|_| "_".to_owned());
format!("&[{type_argument_name}]")
}
ReferenceConversionType::Dereferenced => {
@@ -860,8 +858,8 @@ impl<'db> ReferenceConversion<'db> {
.type_arguments()
.next()
.unwrap()
- .display(db, display_target)
- .to_string();
+ .display_source_code(db, module.into(), true)
+ .unwrap_or_else(|_| "_".to_owned());
format!("&{type_argument_name}")
}
ReferenceConversionType::Option => {
@@ -870,16 +868,22 @@ impl<'db> ReferenceConversion<'db> {
.type_arguments()
.next()
.unwrap()
- .display(db, display_target)
- .to_string();
+ .display_source_code(db, module.into(), true)
+ .unwrap_or_else(|_| "_".to_owned());
format!("Option<&{type_argument_name}>")
}
ReferenceConversionType::Result => {
let mut type_arguments = self.ty.type_arguments();
- let first_type_argument_name =
- type_arguments.next().unwrap().display(db, display_target).to_string();
- let second_type_argument_name =
- type_arguments.next().unwrap().display(db, display_target).to_string();
+ let first_type_argument_name = type_arguments
+ .next()
+ .unwrap()
+ .display_source_code(db, module.into(), true)
+ .unwrap_or_else(|_| "_".to_owned());
+ let second_type_argument_name = type_arguments
+ .next()
+ .unwrap()
+ .display_source_code(db, module.into(), true)
+ .unwrap_or_else(|_| "_".to_owned());
format!("Result<&{first_type_argument_name}, &{second_type_argument_name}>")
}
};