This commit is contained in:
Andrzej Głuszak 2021-10-20 21:35:35 +02:00
parent 98676efdc5
commit a2242dcf1b
3 changed files with 17 additions and 29 deletions

View file

@ -1,6 +1,7 @@
use rustc_hash::{FxHashMap, FxHashSet}; use rustc_hash::{FxHashMap, FxHashSet};
use hir::{HasSource, HirDisplay, Module, ModuleDef, Semantics, TypeInfo}; use hir::{HasSource, HirDisplay, Module, ModuleDef, Semantics, TypeInfo};
use ide_db::helpers::FamousDefs;
use ide_db::{ use ide_db::{
base_db::FileId, base_db::FileId,
defs::{Definition, NameRefClass}, defs::{Definition, NameRefClass},
@ -512,11 +513,8 @@ fn fn_arg_type(ctx: &AssistContext, target_module: hir::Module, fn_arg: &ast::Ex
} }
if ty.is_reference() || ty.is_mutable_reference() { if ty.is_reference() || ty.is_mutable_reference() {
convert_reference_type( let famous_defs = &FamousDefs(&ctx.sema, ctx.sema.scope(fn_arg.syntax()).krate());
ty.strip_references(), convert_reference_type(ty.strip_references(), ctx.db(), famous_defs)
ctx,
ctx.sema.scope(fn_arg.syntax()).krate(),
)
.map(|conversion| conversion.convert_type(ctx.db())) .map(|conversion| conversion.convert_type(ctx.db()))
.or_else(|| ty.display_source_code(ctx.db(), target_module.into()).ok()) .or_else(|| ty.display_source_code(ctx.db(), target_module.into()).ok())
} else { } else {

View file

@ -1,3 +1,4 @@
use ide_db::helpers::FamousDefs;
use stdx::{format_to, to_lower_snake_case}; use stdx::{format_to, to_lower_snake_case};
use syntax::ast::{self, AstNode, HasName, HasVisibility}; use syntax::ast::{self, AstNode, HasName, HasVisibility};
@ -112,16 +113,12 @@ pub(crate) fn generate_getter_impl(
let vis = strukt.visibility().map_or(String::new(), |v| format!("{} ", v)); let vis = strukt.visibility().map_or(String::new(), |v| format!("{} ", v));
let (ty, body) = if mutable { let (ty, body) = if mutable {
( (format!("&mut {}", field_ty), format!("&mut self.{}", field_name))
format!("&mut {}", field_ty.to_string()),
format!("&mut self.{}", field_name.to_string()),
)
} else { } else {
let famous_defs = &FamousDefs(&ctx.sema, ctx.sema.scope(field_ty.syntax()).krate());
ctx.sema ctx.sema
.resolve_type(&field_ty) .resolve_type(&field_ty)
.and_then(|ty| { .and_then(|ty| convert_reference_type(ty, ctx.db(), famous_defs))
convert_reference_type(ty, ctx, ctx.sema.scope(field_ty.syntax()).krate())
})
.map(|conversion| { .map(|conversion| {
cov_mark::hit!(convert_reference_type); cov_mark::hit!(convert_reference_type);
( (

View file

@ -5,10 +5,10 @@ use std::ops;
use itertools::Itertools; use itertools::Itertools;
pub(crate) use gen_trait_fn_body::gen_trait_fn_body; pub(crate) use gen_trait_fn_body::gen_trait_fn_body;
use hir::db::HirDatabase; use hir::{db::HirDatabase, HasSource, HirDisplay};
use hir::{Crate, HasSource, HirDisplay}; use ide_db::{
use ide_db::helpers::FamousDefs; helpers::FamousDefs, helpers::SnippetCap, path_transform::PathTransform, RootDatabase,
use ide_db::{helpers::SnippetCap, path_transform::PathTransform, RootDatabase}; };
use stdx::format_to; use stdx::format_to;
use syntax::{ use syntax::{
ast::{ ast::{
@ -577,19 +577,13 @@ impl ReferenceConversion {
// FIXME: It should return a new hir::Type, but currently constructing new types is too cumbersome // FIXME: It should return a new hir::Type, but currently constructing new types is too cumbersome
// and all users of this function operate on string type names, so they can do the conversion // and all users of this function operate on string type names, so they can do the conversion
// itself themselves. // itself themselves.
// Another problem is that it probably shouldn't take AssistContext as a parameter, as
// it should be usable not only in assists.
pub(crate) fn convert_reference_type( pub(crate) fn convert_reference_type(
ty: hir::Type, ty: hir::Type,
ctx: &AssistContext, db: &RootDatabase,
krate: Option<Crate>, famous_defs: &FamousDefs,
) -> Option<ReferenceConversion> { ) -> Option<ReferenceConversion> {
let sema = &ctx.sema;
let db = sema.db;
let famous_defs = &FamousDefs(sema, krate);
handle_copy(&ty, db) handle_copy(&ty, db)
.or_else(|| handle_as_ref_str(&ty, db, famous_defs, ctx)) .or_else(|| handle_as_ref_str(&ty, db, famous_defs))
.or_else(|| handle_as_ref_slice(&ty, db, famous_defs)) .or_else(|| handle_as_ref_slice(&ty, db, famous_defs))
.or_else(|| handle_dereferenced(&ty, db, famous_defs)) .or_else(|| handle_dereferenced(&ty, db, famous_defs))
.or_else(|| handle_option_as_ref(&ty, db, famous_defs)) .or_else(|| handle_option_as_ref(&ty, db, famous_defs))
@ -605,9 +599,8 @@ fn handle_as_ref_str(
ty: &hir::Type, ty: &hir::Type,
db: &dyn HirDatabase, db: &dyn HirDatabase,
famous_defs: &FamousDefs, famous_defs: &FamousDefs,
ctx: &AssistContext,
) -> Option<ReferenceConversionType> { ) -> Option<ReferenceConversionType> {
let module = ctx.sema.to_module_def(ctx.file_id())?; let module = famous_defs.1?.root_module(db);
let str_type = hir::BuiltinType::str().ty(db, module); let str_type = hir::BuiltinType::str().ty(db, module);
ty.impls_trait(db, famous_defs.core_convert_AsRef()?, &[str_type]) ty.impls_trait(db, famous_defs.core_convert_AsRef()?, &[str_type])