@@ -15,6 +15,7 @@ use crate::{
15
15
// Generates default implementation from new method.
16
16
//
17
17
// ```
18
+ // # //- minicore: default
18
19
// struct Example { _inner: () }
19
20
//
20
21
// impl Example {
@@ -54,6 +55,7 @@ pub(crate) fn generate_default_from_new(acc: &mut Assists, ctx: &AssistContext<'
54
55
}
55
56
56
57
let impl_ = fn_node. syntax ( ) . ancestors ( ) . find_map ( ast:: Impl :: cast) ?;
58
+ let self_ty = impl_. self_ty ( ) ?;
57
59
if is_default_implemented ( ctx, & impl_) {
58
60
cov_mark:: hit!( default_block_is_already_present) ;
59
61
cov_mark:: hit!( struct_in_module_with_default) ;
@@ -70,15 +72,19 @@ pub(crate) fn generate_default_from_new(acc: &mut Assists, ctx: &AssistContext<'
70
72
let default_code = " fn default() -> Self {
71
73
Self::new()
72
74
}" ;
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) ;
74
76
builder. insert ( insert_location. end ( ) , code) ;
75
77
} ,
76
78
)
77
79
}
78
80
79
81
// 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 {
82
88
let generic_params = impl_. generic_param_list ( ) . map ( |generic_params| {
83
89
let lifetime_params =
84
90
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:
109
115
if let Some ( generic_params) = & generic_params {
110
116
format_to ! ( buf, "{generic_params}" )
111
117
}
112
- format_to ! ( buf, " {trait_text} for {impl_ty }" ) ;
118
+ format_to ! ( buf, " {trait_text} for {self_ty }" ) ;
113
119
114
120
match impl_. where_clause ( ) {
115
121
Some ( where_clause) => {
@@ -136,7 +142,9 @@ fn is_default_implemented(ctx: &AssistContext<'_>, impl_: &Impl) -> bool {
136
142
let default = FamousDefs ( & ctx. sema , krate) . core_default_Default ( ) ;
137
143
let default_trait = match default {
138
144
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 ,
140
148
} ;
141
149
142
150
ty. impls_trait ( db, default_trait, & [ ] )
@@ -480,6 +488,7 @@ impl Example {
480
488
check_assist_not_applicable (
481
489
generate_default_from_new,
482
490
r#"
491
+ //- minicore: default
483
492
struct Example { _inner: () }
484
493
485
494
impl Example {
@@ -655,4 +664,23 @@ mod test {
655
664
"# ,
656
665
) ;
657
666
}
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
+ }
658
686
}
0 commit comments