Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/generate_single_field_struct_from.rs')
-rw-r--r--crates/ide-assists/src/handlers/generate_single_field_struct_from.rs17
1 files changed, 14 insertions, 3 deletions
diff --git a/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs b/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs
index 6076d5cb5c..deef4a9aac 100644
--- a/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs
+++ b/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs
@@ -1,4 +1,5 @@
use ast::make;
+use hir::next_solver::{DbInterner, TypingMode};
use hir::{HasCrate, ModuleDef, Semantics};
use ide_db::{
RootDatabase, famous_defs::FamousDefs, helpers::mod_path_to_ast,
@@ -47,6 +48,7 @@ pub(crate) fn generate_single_field_struct_from(
let strukt_name = ctx.find_node_at_offset::<ast::Name>()?;
let adt = ast::Adt::cast(strukt_name.syntax().parent()?)?;
let ast::Adt::Struct(strukt) = adt else {
+ tracing::debug!(?adt);
return None;
};
@@ -57,10 +59,12 @@ pub(crate) fn generate_single_field_struct_from(
let constructors = make_constructors(ctx, module, &types);
if constructors.iter().filter(|expr| expr.is_none()).count() != 1 {
+ tracing::debug!(?constructors);
return None;
}
let main_field_i = constructors.iter().position(Option::is_none)?;
if from_impl_exists(&strukt, main_field_i, &ctx.sema).is_some() {
+ tracing::debug!(?strukt, ?main_field_i);
return None;
}
@@ -200,6 +204,7 @@ fn get_fields(strukt: &ast::Struct) -> Option<(Option<Vec<ast::Name>>, Vec<ast::
})
}
+#[tracing::instrument(ret)]
fn from_impl_exists(
strukt: &ast::Struct,
main_field_i: usize,
@@ -209,9 +214,15 @@ fn from_impl_exists(
let strukt = sema.to_def(strukt)?;
let krate = strukt.krate(db);
let from_trait = FamousDefs(sema, krate).core_convert_From()?;
- let ty = strukt.fields(db).get(main_field_i)?.ty(db);
-
- strukt.ty(db).impls_trait(db, from_trait, &[ty]).then_some(())
+ let interner = DbInterner::new_with(db, Some(krate.base()), None);
+ use hir::next_solver::infer::DbInternerInferExt;
+ let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
+
+ let strukt = strukt.instantiate_infer(&infcx);
+ let field_ty = strukt.fields(db).get(main_field_i)?.ty(db);
+ let struct_ty = strukt.ty(db);
+ tracing::debug!(?strukt, ?field_ty, ?struct_ty);
+ struct_ty.impls_trait(infcx, from_trait, &[field_ty]).then_some(())
}
#[cfg(test)]