1
1
//! Module responsible for analyzing the code surrounding the cursor for completion.
2
2
use std:: iter;
3
3
4
- use hir:: { Semantics , Type , TypeInfo } ;
4
+ use hir:: { Semantics , Type , TypeInfo , Variant } ;
5
5
use ide_db:: { active_parameter:: ActiveParameter , RootDatabase } ;
6
6
use syntax:: {
7
7
algo:: { find_node_at_offset, non_trivia_sibling} ,
@@ -1111,6 +1111,9 @@ fn pattern_context_for(
1111
1111
pat : ast:: Pat ,
1112
1112
) -> PatternContext {
1113
1113
let mut param_ctx = None ;
1114
+
1115
+ let mut missing_variants = vec ! [ ] ;
1116
+
1114
1117
let ( refutability, has_type_ascription) =
1115
1118
pat
1116
1119
. syntax ( )
@@ -1140,7 +1143,52 @@ fn pattern_context_for(
1140
1143
} ) ( ) ;
1141
1144
return ( PatternRefutability :: Irrefutable , has_type_ascription)
1142
1145
} ,
1143
- ast:: MatchArm ( _) => PatternRefutability :: Refutable ,
1146
+ ast:: MatchArm ( match_arm) => {
1147
+ let missing_variants_opt = match_arm
1148
+ . syntax( )
1149
+ . parent( )
1150
+ . and_then( ast:: MatchArmList :: cast)
1151
+ . and_then( |match_arm_list| {
1152
+ match_arm_list
1153
+ . syntax( )
1154
+ . parent( )
1155
+ . and_then( ast:: MatchExpr :: cast)
1156
+ . and_then( |match_expr| {
1157
+ let expr_opt = find_opt_node_in_file( & original_file, match_expr. expr( ) ) ;
1158
+
1159
+ expr_opt. and_then( |expr| {
1160
+ sema. type_of_expr( & expr) ?
1161
+ . adjusted( )
1162
+ . autoderef( sema. db)
1163
+ . find_map( |ty| match ty. as_adt( ) {
1164
+ Some ( hir:: Adt :: Enum ( e) ) => Some ( e) ,
1165
+ _ => None ,
1166
+ } ) . and_then( |enum_| {
1167
+ Some ( enum_. variants( sema. db) )
1168
+ } )
1169
+ } )
1170
+ } ) . and_then( |variants| {
1171
+ Some ( variants. iter( ) . filter_map( |variant| {
1172
+ let variant_name = variant. name( sema. db) . to_string( ) ;
1173
+
1174
+ let variant_already_present = match_arm_list. arms( ) . any( |arm| {
1175
+ arm. pat( ) . and_then( |pat| {
1176
+ let pat_already_present = pat. syntax( ) . to_string( ) . contains( & variant_name) ;
1177
+ pat_already_present. then( || pat_already_present)
1178
+ } ) . is_some( )
1179
+ } ) ;
1180
+
1181
+ ( !variant_already_present) . then_some( variant. clone( ) )
1182
+ } ) . collect:: <Vec <Variant >>( ) )
1183
+ } )
1184
+ } ) ;
1185
+
1186
+ if let Some ( missing_variants_) = missing_variants_opt {
1187
+ missing_variants = missing_variants_;
1188
+ } ;
1189
+
1190
+ PatternRefutability :: Refutable
1191
+ } ,
1144
1192
ast:: LetExpr ( _) => PatternRefutability :: Refutable ,
1145
1193
ast:: ForExpr ( _) => PatternRefutability :: Irrefutable ,
1146
1194
_ => PatternRefutability :: Irrefutable ,
@@ -1162,6 +1210,7 @@ fn pattern_context_for(
1162
1210
ref_token,
1163
1211
record_pat : None ,
1164
1212
impl_ : fetch_immediate_impl ( sema, original_file, pat. syntax ( ) ) ,
1213
+ missing_variants,
1165
1214
}
1166
1215
}
1167
1216
0 commit comments