pub(crate) fn find_struct_impl(
    ctx: &AssistContext,
    strukt: &ast::AdtDef,
    name: &str,
) -> Option<Option<ast::Impl>> {
    let db = ctx.db();
    let module = strukt.syntax().ancestors().find(|node| {
        ast::Module::can_cast(node.kind()) || ast::SourceFile::can_cast(node.kind())
    })?;

    let struct_def = match strukt {
        ast::AdtDef::Enum(e) => Adt::Enum(ctx.sema.to_def(e)?),
        ast::AdtDef::Struct(s) => Adt::Struct(ctx.sema.to_def(s)?),
        ast::AdtDef::Union(u) => Adt::Union(ctx.sema.to_def(u)?),
    };

    let block = module.descendants().filter_map(ast::Impl::cast).find_map(|impl_blk| {
        let blk = ctx.sema.to_def(&impl_blk)?;

        // FIXME: handle e.g. `struct S<T>; impl<U> S<U> {}`
        // (we currently use the wrong type parameter)
        // also we wouldn't want to use e.g. `impl S<u32>`

        let same_ty = match blk.target_ty(db).as_adt() {
            Some(def) => def == struct_def,
            None => false,
        };
        let not_trait_impl = blk.target_trait(db).is_none();

        if !(same_ty && not_trait_impl) {
            None
        } else {
            Some(impl_blk)
        }
    });

    if let Some(ref impl_blk) = block {
        if has_fn(impl_blk, name) {
            return None;
        }
    }

    Some(block)
}
// Uses a syntax-driven approach to find any impl blocks for the struct that
// exist within the module/file
//
// Returns `None` if we've found an existing fn
//
// FIXME: change the new fn checking to a more semantic approach when that's more
// viable (e.g. we process proc macros, etc)
// FIXME: this partially overlaps with `find_impl_block`
Uses a syntax-driven approach to find any impl blocks for the struct that
exist within the module/file

Returns `None` if we've found an existing fn

change the new fn checking to a more semantic approach when that's more
viable
FIXME: this partially overlaps with `find_impl_block`
Uses a syntax - driven approach to find any impl blocks for the struct that exist within the module / file Returns ` None ` if we ' ve found an existing fn change the new fn checking to a more semantic approach when that ' s more viable FIXME : this partially overlaps with ` find_impl_block `
pub(crate) fn find_struct_impl(
    ctx: &AssistContext,
    strukt: &ast::AdtDef,
    name: &str,
) -> Option<Option<ast::Impl>> {
    let db = ctx.db();
    let module = strukt.syntax().ancestors().find(|node| {
        ast::Module::can_cast(node.kind()) || ast::SourceFile::can_cast(node.kind())
    })?;
    let struct_def = match strukt {
        ast::AdtDef::Enum(e) => Adt::Enum(ctx.sema.to_def(e)?),
        ast::AdtDef::Struct(s) => Adt::Struct(ctx.sema.to_def(s)?),
        ast::AdtDef::Union(u) => Adt::Union(ctx.sema.to_def(u)?),
    };
    let block = module.descendants().filter_map(ast::Impl::cast).find_map(|impl_blk| {
        let blk = ctx.sema.to_def(&impl_blk)?;
        // FIXME: handle e.g. `struct S<T>; impl<U> S<U> {}`
        // (we currently use the wrong type parameter)
        // also we wouldn't want to use e.g. `impl S<u32>`
        let same_ty = match blk.target_ty(db).as_adt() {
            Some(def) => def == struct_def,
            None => false,
        };
        let not_trait_impl = blk.target_trait(db).is_none();
        if !(same_ty && not_trait_impl) {
            None
        } else {
            Some(impl_blk)
        }
    });
    if let Some(ref impl_blk) = block {
        if has_fn(impl_blk, name) {
            return None;
        }
    }
    Some(block)
}
pub ( crate ) fn find_struct_impl ( ctx : & AssistContext , strukt : & ast :: AdtDef , name : & str , ) -> Option < Option < ast :: Impl > > { let db = ctx . db ( ) ; let module = strukt . syntax ( ) . ancestors ( ) . find ( | node | { ast :: Module :: can_cast ( node . kind ( ) ) || ast :: SourceFile :: can_cast ( node . kind ( ) ) } ) ? ; let struct_def = match strukt { ast :: AdtDef :: Enum ( e ) => Adt :: Enum ( ctx . sema . to_def ( e ) ? ) , ast :: AdtDef :: Struct ( s ) => Adt :: Struct ( ctx . sema . to_def ( s ) ? ) , ast :: AdtDef :: Union ( u ) => Adt :: Union ( ctx . sema . to_def ( u ) ? ) , } ; let block = module . descendants ( ) . filter_map ( ast :: Impl :: cast ) . find_map ( | impl_blk | { let blk = ctx . sema . to_def ( & impl_blk ) ? ; // FIXME: handle e.g. `struct S<T>; impl<U> S<U> {}` // (we currently use the wrong type parameter) // also we wouldn't want to use e.g. `impl S<u32>` let same_ty = match blk . target_ty ( db ) . as_adt ( ) { Some ( def ) => def == struct_def , None => false , } ; let not_trait_impl = blk . target_trait ( db ) . is_none ( ) ; if ! ( same_ty && not_trait_impl ) { None } else { Some ( impl_blk ) } } ) ; if let Some ( ref impl_blk ) = block { if has_fn ( impl_blk , name ) { return None ; } } Some ( block ) }
Uses a syntax-driven approach to find any impl blocks for the struct that
exist within the module/file
Uses a syntax - driven approach to find any impl blocks for the struct that exist within the module / file
ctx
&AssistContext
strukt
&ast::AdtDef
name
&str
ctx
&AssistContext
strukt
&ast::AdtDef
name
&str