1- //! FIXME: write short doc here
1+ //! Collects diagnostics & fixits for a single file.
2+ //!
3+ //! The tricky bit here is that diagnostics are produced by hir in terms of
4+ //! macro-expanded files, but we need to present them to the users in terms of
5+ //! original files. So we need to map the ranges.
26
37use std:: cell:: RefCell ;
48
@@ -46,7 +50,7 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
4650 let mut sink = DiagnosticSink :: new ( |d| {
4751 res. borrow_mut ( ) . push ( Diagnostic {
4852 message : d. message ( ) ,
49- range : d . highlight_range ( ) ,
53+ range : sema . diagnostics_range ( d ) . range ,
5054 severity : Severity :: Error ,
5155 fix : None ,
5256 } )
@@ -62,7 +66,7 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
6266 let create_file = FileSystemEdit :: CreateFile { source_root, path } ;
6367 let fix = SourceChange :: file_system_edit ( "create module" , create_file) ;
6468 res. borrow_mut ( ) . push ( Diagnostic {
65- range : d . highlight_range ( ) ,
69+ range : sema . diagnostics_range ( d ) . range ,
6670 message : d. message ( ) ,
6771 severity : Severity :: Error ,
6872 fix : Some ( fix) ,
@@ -95,15 +99,15 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
9599 } ;
96100
97101 res. borrow_mut ( ) . push ( Diagnostic {
98- range : d . highlight_range ( ) ,
102+ range : sema . diagnostics_range ( d ) . range ,
99103 message : d. message ( ) ,
100104 severity : Severity :: Error ,
101105 fix,
102106 } )
103107 } )
104108 . on :: < hir:: diagnostics:: MissingMatchArms , _ > ( |d| {
105109 res. borrow_mut ( ) . push ( Diagnostic {
106- range : d . highlight_range ( ) ,
110+ range : sema . diagnostics_range ( d ) . range ,
107111 message : d. message ( ) ,
108112 severity : Severity :: Error ,
109113 fix : None ,
@@ -115,7 +119,7 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
115119 let edit = TextEdit :: replace ( node. syntax ( ) . text_range ( ) , replacement) ;
116120 let fix = SourceChange :: source_file_edit_from ( "wrap with ok" , file_id, edit) ;
117121 res. borrow_mut ( ) . push ( Diagnostic {
118- range : d . highlight_range ( ) ,
122+ range : sema . diagnostics_range ( d ) . range ,
119123 message : d. message ( ) ,
120124 severity : Severity :: Error ,
121125 fix : Some ( fix) ,
@@ -621,6 +625,62 @@ mod tests {
621625 "### ) ;
622626 }
623627
628+ #[ test]
629+ fn range_mapping_out_of_macros ( ) {
630+ let ( analysis, file_id) = single_file (
631+ r"
632+ fn some() {}
633+ fn items() {}
634+ fn here() {}
635+
636+ macro_rules! id {
637+ ($($tt:tt)*) => { $($tt)*};
638+ }
639+
640+ fn main() {
641+ let _x = id![Foo { a: 42 }];
642+ }
643+
644+ pub struct Foo {
645+ pub a: i32,
646+ pub b: i32,
647+ }
648+ " ,
649+ ) ;
650+ let diagnostics = analysis. diagnostics ( file_id) . unwrap ( ) ;
651+ assert_debug_snapshot ! ( diagnostics, @r###"
652+ [
653+ Diagnostic {
654+ message: "Missing structure fields:\n- b",
655+ range: [224; 233),
656+ fix: Some(
657+ SourceChange {
658+ label: "fill struct fields",
659+ source_file_edits: [
660+ SourceFileEdit {
661+ file_id: FileId(
662+ 1,
663+ ),
664+ edit: TextEdit {
665+ atoms: [
666+ AtomTextEdit {
667+ delete: [3; 9),
668+ insert: "{a:42, b: ()}",
669+ },
670+ ],
671+ },
672+ },
673+ ],
674+ file_system_edits: [],
675+ cursor_position: None,
676+ },
677+ ),
678+ severity: Error,
679+ },
680+ ]
681+ "### ) ;
682+ }
683+
624684 #[ test]
625685 fn test_check_unnecessary_braces_in_use_statement ( ) {
626686 check_not_applicable (
0 commit comments