From 714836959be857e2fbd9c497974055deb2a91f9b Mon Sep 17 00:00:00 2001 From: Chetan Khilosiya Date: Tue, 16 Mar 2021 01:16:59 +0530 Subject: 7709: Added the check for return type of len function. --- crates/hir/src/lib.rs | 7 +++++ .../src/handlers/generate_is_empty_from_len.rs | 35 ++++++++++++++++------ 2 files changed, 33 insertions(+), 9 deletions(-) (limited to 'crates') diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index c5161dadd..1a1454068 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -1631,6 +1631,13 @@ impl Type { matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) } + pub fn is_usize(&self) -> bool { + matches!( + self.ty.value.interned(&Interner), + TyKind::Scalar(Scalar::Uint(hir_ty::primitive::UintTy::Usize)) + ) + } + pub fn remove_ref(&self) -> Option { match &self.ty.value.interned(&Interner) { TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), diff --git a/crates/ide_assists/src/handlers/generate_is_empty_from_len.rs b/crates/ide_assists/src/handlers/generate_is_empty_from_len.rs index aa7072f25..b8834d283 100644 --- a/crates/ide_assists/src/handlers/generate_is_empty_from_len.rs +++ b/crates/ide_assists/src/handlers/generate_is_empty_from_len.rs @@ -1,7 +1,7 @@ use hir::{known, HasSource, Name}; use syntax::{ ast::{self, NameOwner}, - AstNode, TextRange, + AstNode, }; use crate::{ @@ -51,12 +51,19 @@ pub(crate) fn generate_is_empty_from_len(acc: &mut Assists, ctx: &AssistContext) } let impl_ = fn_node.syntax().ancestors().find_map(ast::Impl::cast)?; + let len_fn = get_impl_method(ctx, &impl_, &known::len)?; + if !len_fn.ret_type(ctx.sema.db).is_usize() { + cov_mark::hit!(len_fn_different_return_type); + return None; + } + if get_impl_method(ctx, &impl_, &known::is_empty).is_some() { cov_mark::hit!(is_empty_already_implemented); return None; } - let range = get_text_range_of_len_function(ctx, &impl_)?; + let node = len_fn.source(ctx.sema.db)?; + let range = node.syntax().value.text_range(); acc.add( AssistId("generate_is_empty_from_len", AssistKind::Generate), @@ -89,13 +96,6 @@ fn get_impl_method( ty.iterate_method_candidates(db, krate, &traits_in_scope, Some(fn_name), |_, func| Some(func)) } -fn get_text_range_of_len_function(ctx: &AssistContext, impl_: &ast::Impl) -> Option { - let db = ctx.sema.db; - let func = get_impl_method(ctx, impl_, &known::len)?; - let node = func.source(db)?; - Some(node.syntax().value.text_range()) -} - #[cfg(test)] mod tests { use crate::tests::{check_assist, check_assist_not_applicable}; @@ -157,6 +157,23 @@ impl MyStruct { ); } + #[test] + fn len_fn_different_return_type() { + cov_mark::check!(len_fn_different_return_type); + check_assist_not_applicable( + generate_is_empty_from_len, + r#" +struct MyStruct { data: Vec } + +impl MyStruct { + p$0ub fn len(&self) -> u32 { + self.data.len() + } +} +"#, + ); + } + #[test] fn generate_is_empty() { check_assist( -- cgit v1.2.3