@@ -1135,20 +1135,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1135
1135
}
1136
1136
}
1137
1137
1138
- // // Incorporate the argument changes in the removal suggestion.
1139
- // let mut prev = -1;
1140
- // for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() {
1141
- // if let Some(provided_idx) = provided_idx {
1142
- // prev = provided_idx.index() as i64;
1143
- // }
1144
- // let idx = ProvidedIdx::from_usize((prev + 1) as usize);
1145
- // if let None = provided_idx
1146
- // && let Some((_, arg_span)) = provided_arg_tys.get(idx)
1147
- // {
1148
- // let (_, expected_ty) = formal_and_expected_inputs[expected_idx];
1149
- // suggestions.push((*arg_span, ty_to_snippet(expected_ty, expected_idx)));
1150
- // }
1151
- // }
1138
+ // Incorporate the argument changes in the removal suggestion.
1139
+ // When a type is *missing*, and the rest are additional, we want to suggest these with a
1140
+ // multipart suggestion, but in order to do so we need to figure out *where* the arg that
1141
+ // was provided but had the wrong type should go, because when looking at `expected_idx`
1142
+ // that is the position in the argument list in the definition, while `provided_idx` will
1143
+ // not be present. So we have to look at what the *last* provided position was, and point
1144
+ // one after to suggest the replacement. FIXME(estebank): This is hacky, and there's
1145
+ // probably a better more involved change we can make to make this work.
1146
+ // For example, if we have
1147
+ // ```
1148
+ // fn foo(i32, &'static str) {}
1149
+ // foo((), (), ());
1150
+ // ```
1151
+ // what should be suggested is
1152
+ // ```
1153
+ // foo(/* i32 */, /* &str */);
1154
+ // ```
1155
+ // which includes the replacement of the first two `()` for the correct type, and the
1156
+ // removal of the last `()`.
1157
+ let mut prev = -1 ;
1158
+ for ( expected_idx, provided_idx) in matched_inputs. iter_enumerated ( ) {
1159
+ // We want to point not at the *current* argument expression index, but rather at the
1160
+ // index position where it *should have been*, which is *after* the previous one.
1161
+ if let Some ( provided_idx) = provided_idx {
1162
+ prev = provided_idx. index ( ) as i64 ;
1163
+ }
1164
+ let idx = ProvidedIdx :: from_usize ( ( prev + 1 ) as usize ) ;
1165
+ if let None = provided_idx
1166
+ && let Some ( ( _, arg_span) ) = provided_arg_tys. get ( idx)
1167
+ {
1168
+ // There is a type that was *not* found anywhere, so it isn't a move, but a
1169
+ // replacement and we look at what type it should have been. This will allow us
1170
+ // To suggest a multipart suggestion when encountering `foo(1, "")` where the def
1171
+ // was `fn foo(())`.
1172
+ let ( _, expected_ty) = formal_and_expected_inputs[ expected_idx] ;
1173
+ suggestions. push ( ( * arg_span, ty_to_snippet ( expected_ty, expected_idx) ) ) ;
1174
+ }
1175
+ }
1152
1176
1153
1177
// If we have less than 5 things to say, it would be useful to call out exactly what's wrong
1154
1178
if labels. len ( ) <= 5 {
0 commit comments