@@ -13,7 +13,7 @@ use syntax::{
13
13
ast:: { self , make} ,
14
14
AstNode , SyntaxNode , SyntaxNodePtr ,
15
15
} ;
16
- use text_edit:: TextEdit ;
16
+ use text_edit:: { TextEdit , TextRange } ;
17
17
18
18
use crate :: { fix, Diagnostic , DiagnosticCode , DiagnosticsContext } ;
19
19
@@ -40,12 +40,17 @@ pub(crate) fn missing_fields(ctx: &DiagnosticsContext<'_>, d: &hir::MissingField
40
40
. map ( SyntaxNodePtr :: from)
41
41
. unwrap_or_else ( || d. field_list_parent . into ( ) ) ,
42
42
) ;
43
+ let range = ptr. value . text_range ( ) ;
43
44
44
45
Diagnostic :: new_with_syntax_node_ptr ( ctx, DiagnosticCode :: RustcHardError ( "E0063" ) , message, ptr)
45
- . with_fixes ( fixes ( ctx, d) )
46
+ . with_fixes ( fixes ( ctx, d, range ) )
46
47
}
47
48
48
- fn fixes ( ctx : & DiagnosticsContext < ' _ > , d : & hir:: MissingFields ) -> Option < Vec < Assist > > {
49
+ fn fixes (
50
+ ctx : & DiagnosticsContext < ' _ > ,
51
+ d : & hir:: MissingFields ,
52
+ range : TextRange ,
53
+ ) -> Option < Vec < Assist > > {
49
54
// Note that although we could add a diagnostics to
50
55
// fill the missing tuple field, e.g :
51
56
// `struct A(usize);`
@@ -60,27 +65,27 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass
60
65
let current_module =
61
66
ctx. sema . scope ( d. field_list_parent . to_node ( & root) . syntax ( ) ) . map ( |it| it. module ( ) ) ;
62
67
63
- let build_text_edit = |parent_syntax, new_syntax : & SyntaxNode , old_syntax| {
64
- let edit = {
68
+ let build_text_edit = |new_syntax : & SyntaxNode , old_syntax| {
69
+ let ( file_id, edit) = {
70
+ let range = ctx. sema . original_range_opt ( old_syntax) ?;
65
71
let mut builder = TextEdit :: builder ( ) ;
66
72
if d. file . is_macro ( ) {
67
73
// we can't map the diff up into the macro input unfortunately, as the macro loses all
68
74
// whitespace information so the diff wouldn't be applicable no matter what
69
75
// This has the downside that the cursor will be moved in macros by doing it without a diff
70
76
// but that is a trade off we can make.
71
77
// FIXME: this also currently discards a lot of whitespace in the input... we really need a formatter here
72
- let range = ctx. sema . original_range_opt ( old_syntax) ?;
73
78
builder. replace ( range. range , new_syntax. to_string ( ) ) ;
74
79
} else {
75
80
algo:: diff ( old_syntax, new_syntax) . into_text_edit ( & mut builder) ;
76
81
}
77
- builder. finish ( )
82
+ ( range . file_id , builder. finish ( ) )
78
83
} ;
79
84
Some ( vec ! [ fix(
80
85
"fill_missing_fields" ,
81
86
"Fill struct fields" ,
82
- SourceChange :: from_text_edit( d . file . original_file ( ctx . sema . db ) , edit) ,
83
- ctx . sema . original_range ( parent_syntax ) . range,
87
+ SourceChange :: from_text_edit( file_id , edit) ,
88
+ range,
84
89
) ] )
85
90
} ;
86
91
@@ -143,11 +148,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass
143
148
) ;
144
149
new_field_list. add_field ( field. clone_for_update ( ) ) ;
145
150
}
146
- build_text_edit (
147
- field_list_parent. syntax ( ) ,
148
- new_field_list. syntax ( ) ,
149
- old_field_list. syntax ( ) ,
150
- )
151
+ build_text_edit ( new_field_list. syntax ( ) , old_field_list. syntax ( ) )
151
152
}
152
153
Either :: Right ( field_list_parent) => {
153
154
let missing_fields = ctx. sema . record_pattern_missing_fields ( field_list_parent) ;
@@ -160,11 +161,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass
160
161
) ) ;
161
162
new_field_list. add_field ( field. clone_for_update ( ) ) ;
162
163
}
163
- build_text_edit (
164
- field_list_parent. syntax ( ) ,
165
- new_field_list. syntax ( ) ,
166
- old_field_list. syntax ( ) ,
167
- )
164
+ build_text_edit ( new_field_list. syntax ( ) , old_field_list. syntax ( ) )
168
165
}
169
166
}
170
167
}
0 commit comments