@@ -15,6 +15,7 @@ use crate::{
1515// Generates default implementation from new method.
1616//
1717// ```
18+ // # //- minicore: default
1819// struct Example { _inner: () }
1920//
2021// impl Example {
@@ -54,6 +55,7 @@ pub(crate) fn generate_default_from_new(acc: &mut Assists, ctx: &AssistContext<'
5455 }
5556
5657 let impl_ = fn_node. syntax ( ) . ancestors ( ) . find_map ( ast:: Impl :: cast) ?;
58+ let self_ty = impl_. self_ty ( ) ?;
5759 if is_default_implemented ( ctx, & impl_) {
5860 cov_mark:: hit!( default_block_is_already_present) ;
5961 cov_mark:: hit!( struct_in_module_with_default) ;
@@ -70,15 +72,19 @@ pub(crate) fn generate_default_from_new(acc: &mut Assists, ctx: &AssistContext<'
7072 let default_code = " fn default() -> Self {
7173 Self::new()
7274 }" ;
73- let code = generate_trait_impl_text_from_impl ( & impl_, "Default" , default_code) ;
75+ let code = generate_trait_impl_text_from_impl ( & impl_, self_ty , "Default" , default_code) ;
7476 builder. insert ( insert_location. end ( ) , code) ;
7577 } ,
7678 )
7779}
7880
7981// FIXME: based on from utils::generate_impl_text_inner
80- fn generate_trait_impl_text_from_impl ( impl_ : & ast:: Impl , trait_text : & str , code : & str ) -> String {
81- let impl_ty = impl_. self_ty ( ) . unwrap ( ) ;
82+ fn generate_trait_impl_text_from_impl (
83+ impl_ : & ast:: Impl ,
84+ self_ty : ast:: Type ,
85+ trait_text : & str ,
86+ code : & str ,
87+ ) -> String {
8288 let generic_params = impl_. generic_param_list ( ) . map ( |generic_params| {
8389 let lifetime_params =
8490 generic_params. lifetime_params ( ) . map ( ast:: GenericParam :: LifetimeParam ) ;
@@ -109,7 +115,7 @@ fn generate_trait_impl_text_from_impl(impl_: &ast::Impl, trait_text: &str, code:
109115 if let Some ( generic_params) = & generic_params {
110116 format_to ! ( buf, "{generic_params}" )
111117 }
112- format_to ! ( buf, " {trait_text} for {impl_ty }" ) ;
118+ format_to ! ( buf, " {trait_text} for {self_ty }" ) ;
113119
114120 match impl_. where_clause ( ) {
115121 Some ( where_clause) => {
@@ -136,7 +142,9 @@ fn is_default_implemented(ctx: &AssistContext<'_>, impl_: &Impl) -> bool {
136142 let default = FamousDefs ( & ctx. sema , krate) . core_default_Default ( ) ;
137143 let default_trait = match default {
138144 Some ( value) => value,
139- None => return false ,
145+ // Return `true` to avoid providing the assist because it makes no sense
146+ // to impl `Default` when it's missing.
147+ None => return true ,
140148 } ;
141149
142150 ty. impls_trait ( db, default_trait, & [ ] )
@@ -480,6 +488,7 @@ impl Example {
480488 check_assist_not_applicable (
481489 generate_default_from_new,
482490 r#"
491+ //- minicore: default
483492struct Example { _inner: () }
484493
485494impl Example {
@@ -655,4 +664,23 @@ mod test {
655664"# ,
656665 ) ;
657666 }
667+
668+ #[ test]
669+ fn not_applicable_when_default_lang_item_is_missing ( ) {
670+ check_assist_not_applicable (
671+ generate_default_from_new,
672+ r#"
673+ struct S;
674+ impl S {
675+ fn new$0() -> Self {}
676+ }
677+ "# ,
678+ ) ;
679+ }
680+
681+ #[ test]
682+ fn not_applicable_for_missing_self_ty ( ) {
683+ // Regression test for #15398.
684+ check_assist_not_applicable ( generate_default_from_new, "impl { fn new$0() -> Self {} }" ) ;
685+ }
658686}
0 commit comments