Repository: rust-analyzer/rust-analyzer
Pull request #10804 (2021-11-18 21:18:17)

fix: Diagnose using `derive` on non-adt items


Patch:
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs
index 2f6eed82cb..c7a8463a3c 100644
--- a/crates/hir/src/attrs.rs
+++ b/crates/hir/src/attrs.rs
@@ -147,7 +147,7 @@ fn resolve_doc_path(
         AttrDefId::MacroDefId(_) => return None,
     };
     let path = ast::Path::parse(link).ok()?;
-    let modpath = ModPath::from_src(db.upcast(), path, &Hygiene::new_unhygienic())?;
+    let modpath = ModPath::from_src(db.upcast(), path, &Hygiene::new_unhygienic()).unwrap();
     let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
     let resolved = if resolved == PerNs::none() {
         resolver.resolve_module_path_in_trait_assoc_items(db.upcast(), &modpath)?
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs
index 0f1963e831..5c4104baae 100644
--- a/crates/hir/src/diagnostics.rs
+++ b/crates/hir/src/diagnostics.rs
@@ -32,6 +32,7 @@ diagnostics![
     BreakOutsideOfLoop,
     InactiveCode,
     IncorrectCase,
+    InvalidDeriveTarget,
     MacroError,
     MismatchedArgCount,
     MissingFields,
@@ -98,6 +99,11 @@ pub struct UnimplementedBuiltinMacro {
     pub node: InFile<SyntaxNodePtr>,
 }
 
+#[derive(Debug)]
+pub struct InvalidDeriveTarget {
+    pub node: InFile<SyntaxNodePtr>,
+}
+
 #[derive(Debug)]
 pub struct NoSuchField {
     pub field: InFile<AstPtr<ast::RecordExprField>>,
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 4fdcb88bbf..7a1b4fd31c 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -83,10 +83,10 @@ pub use crate::{
     attrs::{HasAttrs, Namespace},
     diagnostics::{
         AddReferenceHere, AnyDiagnostic, BreakOutsideOfLoop, InactiveCode, IncorrectCase,
-        MacroError, MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr,
-        MissingUnsafe, NoSuchField, RemoveThisSemicolon, ReplaceFilterMapNextWithFindMap,
-        UnimplementedBuiltinMacro, UnresolvedExternCrate, UnresolvedImport, UnresolvedMacroCall,
-        UnresolvedModule, UnresolvedProcMacro,
+        InvalidDeriveTarget, MacroError, MismatchedArgCount, MissingFields, MissingMatchArms,
+        MissingOkOrSomeInTailExpr, MissingUnsafe, NoSuchField, RemoveThisSemicolon,
+        ReplaceFilterMapNextWithFindMap, UnimplementedBuiltinMacro, UnresolvedExternCrate,
+        UnresolvedImport, UnresolvedMacroCall, UnresolvedModule, UnresolvedProcMacro,
     },
     has_source::HasSource,
     semantics::{PathResolution, Semantics, SemanticsScope, TypeInfo},
@@ -654,6 +654,21 @@ impl Module {
                         .into(),
                     );
                 }
+                DefDiagnosticKind::InvalidDeriveTarget { ast, id } => {
+                    let node = ast.to_node(db.upcast());
+                    let derive = node.attrs().nth(*id as usize);
+                    match derive {
+                        Some(derive) => {
+                            acc.push(
+                                InvalidDeriveTarget {
+                                    node: ast.with_value(SyntaxNodePtr::from(AstPtr::new(&derive))),
+                                }
+                                .into(),
+                            );
+                        }
+                        None => stdx::never!("derive diagnostic on item without derive attribute"),
+                    }
+                }
             }
         }
         for decl in self.declarations(db) {
@@ -1457,10 +1472,6 @@ impl Const {
         db.const_data(self.id).name.clone()
     }
 
-    pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> {
-        self.source(db)?.value.body()
-    }
-
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
         let data = db.const_data(self.id);
         let resolver = self.id.resolver(db.upcast());
@@ -1497,10 +1508,6 @@ impl Static {
         db.static_data(self.id).mutable
     }
 
-    pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> {
-        self.source(db)?.value.body()
-    }
-
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
         let data = db.static_data(self.id);
         let resolver = self.id.resolver(db.upcast());
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 964af8a8a4..343e189046 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -1055,13 +1055,10 @@ impl DefCollector<'_> {
                         &resolver,
                         &mut |_err| (),
                     );
-                    match call_id {
-                        Ok(Ok(call_id)) => {
-                            resolved.push((directive.module_id, call_id, directive.depth));
-                            res = ReachedFixedPoint::No;
-                            return false;
-                        }
-                        Err(UnresolvedMacro { .. }) | Ok(Err(_)) => {}
+                    if let Ok(Ok(call_id)) = call_id {
+                        resolved.push((directive.module_id, call_id, directive.depth));
+                        res = ReachedFixedPoint::No;
+                        return false;
                     }
                 }
                 MacroDirectiveKind::Derive { ast_id, derive_attr } => {
@@ -1072,19 +1069,16 @@ impl DefCollector<'_> {
                         self.def_map.krate,
                         &resolver,
                     );
-                    match call_id {
-                        Ok(call_id) => {
-                            self.def_map.modules[directive.module_id].scope.add_derive_macro_invoc(
-                                ast_id.ast_id,
-                                call_id,
-                                *derive_attr,
-                            );
+                    if let Ok(call_id) = call_id {
+                        self.def_map.modules[directive.module_id].scope.add_derive_macro_invoc(
+                            ast_id.ast_id,
+                            call_id,
+                            *derive_attr,
+                        );
 
-                            resolved.push((directive.module_id, call_id, directive.depth));
-                            res = ReachedFixedPoint::No;
-                            return false;
-                        }
-                        Err(UnresolvedMacro { .. }) => {}
+                        resolved.push((directive.module_id, call_id, directive.depth));
+                        res = ReachedFixedPoint::No;
+                        return false;
                     }
                 }
                 MacroDirectiveKind::Attr { ast_id, mod_item, attr } => {
@@ -1125,7 +1119,6 @@ impl DefCollector<'_> {
                         if expander.is_derive()
                     ) {
                         // Resolved to `#[derive]`
-                        let file_id = ast_id.ast_id.file_id;
                         let item_tree = self.db.file_item_tree(file_id);
 
                         let ast_id: FileAstId<ast::Item> = match *mod_item {
@@ -1133,8 +1126,12 @@ impl DefCollector<'_> {
                             ModItem::Union(it) => item_tree[it].ast_id.upcast(),
                             ModItem::Enum(it) => item_tree[it].ast_id.upcast(),
                             _ => {
-                                // Cannot use derive on this item.
-                                // FIXME: diagnose
+                                let diag = DefDiagnostic::invalid_derive_target(
+                                    directive.module_id,
+                                    ast_id.ast_id,
+                                    attr.id,
+                                );
+                                self.def_map.diagnostics.push(diag);
                                 res = ReachedFixedPoint::No;
                                 return false;
                             }
@@ -1194,7 +1191,6 @@ impl DefCollector<'_> {
                                         ),
                                     );
 
-                                    let file_id = ast_id.ast_id.file_id;
                                     let item_tree = self.db.file_item_tree(file_id);
                                     return recollect_without(self, &item_tree);
                                 }
diff --git a/crates/hir_def/src/nameres/diagnostics.rs b/crates/hir_def/src/nameres/diagnostics.rs
index 95061f6015..1eb3844731 100644
--- a/crates/hir_def/src/nameres/diagnostics.rs
+++ b/crates/hir_def/src/nameres/diagnostics.rs
@@ -6,6 +6,7 @@ use la_arena::Idx;
 use syntax::ast;
 
 use crate::{
+    attr::AttrId,
     item_tree::{self, ItemTreeId},
     nameres::LocalModuleId,
     path::ModPath,
@@ -29,6 +30,8 @@ pub enum DefDiagnosticKind {
     MacroError { ast: MacroCallKind, message: String },
 
     UnimplementedBuiltinMacro { ast: AstId<ast::Macro> },
+
+    InvalidDeriveTarget { ast: AstId<ast::Item>, id: u32 },
 }
 
 #[derive(Debug, PartialEq, Eq)]
@@ -102,4 +105,15 @@ impl DefDiagnostic {
     ) -> Self {
         Self { in_module: container, kind: DefDiagnosticKind::UnimplementedBuiltinMacro { ast } }
     }
+
+    pub(super) fn invalid_derive_target(
+        container: LocalModuleId,
+        ast: AstId<ast::Item>,
+        id: AttrId,
+    ) -> Self {
+        Self {
+            in_module: container,
+            kind: DefDiagnosticKind::InvalidDeriveTarget { ast, id: id.ast_index },
+        }
+    }
 }
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 8d24bdcf4f..f4fb52647e 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -11,7 +11,7 @@ use ide_db::{
     base_db::FileRange,
     defs::Definition,
     helpers::{pick_best_token, FamousDefs},
-    FxIndexSet, RootDatabase,
+    RootDatabase,
 };
 use itertools::Itertools;
 use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, T};
@@ -69,7 +69,7 @@ impl HoverAction {
     }
 }
 
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
+#[derive(Debug, Clone, Eq, PartialEq)]
 pub struct HoverGotoTypeData {
     pub mod_path: String,
     pub nav: NavigationTarget,
@@ -136,12 +136,11 @@ pub(crate) fn hover(
         .flatten()
         .unique_by(|&(def, _)| def)
         .filter_map(|(def, node)| hover_for_definition(sema, file_id, def, &node, config))
-        .reduce(|mut acc: HoverResult, HoverResult { markup, actions }| {
+        .reduce(|mut acc, HoverResult { markup, actions }| {
             acc.actions.extend(actions);
             acc.markup = Markup::from(format!("{}\n---\n{}", acc.markup, markup));
             acc
         });
-
     if result.is_none() {
         // fallbacks, show keywords or types
         if let Some(res) = render::keyword(sema, config, &original_token) {
@@ -153,10 +152,7 @@ pub(crate) fn hover(
             return res;
         }
     }
-    result.map(|mut res: HoverResult| {
-        res.actions = dedupe_or_merge_hover_actions(res.actions);
-        RangeInfo::new(original_token.text_range(), res)
-    })
+    result.map(|res| RangeInfo::new(original_token.text_range(), res))
 }
 
 pub(crate) fn hover_for_definition(
@@ -318,7 +314,6 @@ fn goto_type_action_for_def(db: &RootDatabase, def: Definition) -> Option<HoverA
             Definition::Local(it) => it.ty(db),
             Definition::GenericParam(hir::GenericParam::ConstParam(it)) => it.ty(db),
             Definition::Field(field) => field.ty(db),
-            Definition::Function(function) => function.ret_type(db),
             _ => return None,
         };
 
@@ -345,43 +340,3 @@ fn walk_and_push_ty(
         }
     });
 }
-
-fn dedupe_or_merge_hover_actions(actions: Vec<HoverAction>) -> Vec<HoverAction> {
-    let mut deduped_actions = Vec::with_capacity(actions.len());
-    let mut go_to_type_targets = FxIndexSet::default();
-
-    let mut seen_implementation = false;
-    let mut seen_reference = false;
-    let mut seen_runnable = false;
-    for action in actions {
-        match action {
-            HoverAction::GoToType(targets) => {
-                go_to_type_targets.extend(targets);
-            }
-            HoverAction::Implementation(..) => {
-                if !seen_implementation {
-                    seen_implementation = true;
-                    deduped_actions.push(action);
-                }
-            }
-            HoverAction::Reference(..) => {
-                if !seen_reference {
-                    seen_reference = true;
-                    deduped_actions.push(action);
-                }
-            }
-            HoverAction::Runnable(..) => {
-                if !seen_runnable {
-                    seen_runnable = true;
-                    deduped_actions.push(action);
-                }
-            }
-        };
-    }
-
-    if !go_to_type_targets.is_empty() {
-        deduped_actions.push(HoverAction::GoToType(go_to_type_targets.into_iter().collect()));
-    }
-
-    deduped_actions
-}
diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs
index e872d9b1fb..59068028ed 100644
--- a/crates/ide/src/hover/render.rs
+++ b/crates/ide/src/hover/render.rs
@@ -1,6 +1,4 @@
 //! Logic for rendering the different hover messages
-use std::fmt::Display;
-
 use either::Either;
 use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo};
 use ide_db::{
@@ -354,8 +352,8 @@ pub(super) fn definition(
         Definition::Function(it) => label_and_docs(db, it),
         Definition::Adt(it) => label_and_docs(db, it),
         Definition::Variant(it) => label_and_docs(db, it),
-        Definition::Const(it) => label_value_and_docs(db, it, |it| it.value(db)),
-        Definition::Static(it) => label_value_and_docs(db, it, |it| it.value(db)),
+        Definition::Const(it) => label_and_docs(db, it),
+        Definition::Static(it) => label_and_docs(db, it),
         Definition::Trait(it) => label_and_docs(db, it),
         Definition::TypeAlias(it) => label_and_docs(db, it),
         Definition::BuiltinType(it) => {
@@ -383,25 +381,6 @@ where
     (label, docs)
 }
 
-fn label_value_and_docs<D, E, V>(
-    db: &RootDatabase,
-    def: D,
-    value_extractor: E,
-) -> (String, Option<hir::Documentation>)
-where
-    D: HasAttrs + HirDisplay,
-    E: Fn(&D) -> Option<V>,
-    V: Display,
-{
-    let label = if let Some(value) = (value_extractor)(&def) {
-        format!("{} = {}", def.display(db), value)
-    } else {
-        def.display(db).to_string()
-    };
-    let docs = def.attrs(db).docs();
-    (label, docs)
-}
-
 fn definition_mod_path(db: &RootDatabase, def: &Definition) -> Option<String> {
     if let Definition::GenericParam(_) = def {
         return None;
diff --git a/crates/ide_diagnostics/src/handlers/invalid_derive_target.rs b/crates/ide_diagnostics/src/handlers/invalid_derive_target.rs
new file mode 100644
index 0000000000..556d2dc0cb
--- /dev/null
+++ b/crates/ide_diagnostics/src/handlers/invalid_derive_target.rs
@@ -0,0 +1,39 @@
+use crate::{Diagnostic, DiagnosticsContext, Severity};
+
+// Diagnostic: invalid-derive-target
+//
+// This diagnostic is shown when the derive attribute is used on an item other than a `struct`,
+// `enum` or `union`.
+pub(crate) fn invalid_derive_target(
+    ctx: &DiagnosticsContext<'_>,
+    d: &hir::InvalidDeriveTarget,
+) -> Diagnostic {
+    // Use more accurate position if available.
+    let display_range = ctx.sema.diagnostics_display_range(d.node.clone()).range;
+
+    Diagnostic::new(
+        "invalid-derive-target",
+        "`derive` may only be applied to `struct`s, `enum`s and `union`s",
+        display_range,
+    )
+    .severity(Severity::Error)
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::tests::check_diagnostics;
+
+    #[test]
+    fn fails_on_function() {
+        check_diagnostics(
+            r#"
+//- minicore:derive
+mod __ {
+    #[derive()]
+  //^^^^^^^^^^^ error: `derive` may only be applied to `struct`s, `enum`s and `union`s
+    fn main() {}
+}
+            "#,
+        );
+    }
+}
diff --git a/crates/ide_diagnostics/src/lib.rs b/crates/ide_diagnostics/src/lib.rs
index 2f53b647b1..5070f24003 100644
--- a/crates/ide_diagnostics/src/lib.rs
+++ b/crates/ide_diagnostics/src/lib.rs
@@ -28,6 +28,7 @@ mod handlers {
     pub(crate) mod break_outside_of_loop;
     pub(crate) mod inactive_code;
     pub(crate) mod incorrect_case;
+    pub(crate) mod invalid_derive_target;
     pub(crate) mod macro_error;
     pub(crate) mod mismatched_arg_count;
     pub(crate) mod missing_fields;
@@ -195,6 +196,7 @@ pub fn diagnostics(
             AnyDiagnostic::UnresolvedMacroCall(d) => handlers::unresolved_macro_call::unresolved_macro_call(&ctx, &d),
             AnyDiagnostic::UnresolvedModule(d) => handlers::unresolved_module::unresolved_module(&ctx, &d),
             AnyDiagnostic::UnresolvedProcMacro(d) => handlers::unresolved_proc_macro::unresolved_proc_macro(&ctx, &d),
+            AnyDiagnostic::InvalidDeriveTarget(d) => handlers::invalid_derive_target::invalid_derive_target(&ctx, &d),
 
             AnyDiagnostic::InactiveCode(d) => match handlers::inactive_code::inactive_code(&ctx, &d) {
                 Some(it) => it,
diff --git a/crates/parser/src/grammar/patterns.rs b/crates/parser/src/grammar/patterns.rs
index 70ff87b238..9da94ce162 100644
--- a/crates/parser/src/grammar/patterns.rs
+++ b/crates/parser/src/grammar/patterns.rs
@@ -74,11 +74,6 @@ fn pattern_single_r(p: &mut Parser, recovery_set: TokenSet) {
         //         Some(0) | None => (),
         //         Some(1..) => ()
         //     }
-        //
-        //     match (10 as u8, 5 as u8) {
-        //         (0, _) => (),
-        //         (1.., _) => ()
-        //     }
         // }
 
         // FIXME: support half_open_range_patterns (`..=2`),
@@ -90,7 +85,7 @@ fn pattern_single_r(p: &mut Parser, recovery_set: TokenSet) {
 
                 // `0 .. =>` or `let 0 .. =` or `Some(0 .. )`
                 //       ^                ^                ^
-                if p.at(T![=]) | p.at(T![')']) | p.at(T![,]) {
+                if p.at(T![=]) | p.at(T![')']) {
                     // test half_open_range_pat
                     // fn f() { let 0 .. = 1u32; }
                 } else {
diff --git a/crates/proc_macro_srv/src/abis/mod.rs b/crates/proc_macro_srv/src/abis/mod.rs
index 0de15b4832..5d7c623b0a 100644
--- a/crates/proc_macro_srv/src/abis/mod.rs
+++ b/crates/proc_macro_srv/src/abis/mod.rs
@@ -69,26 +69,22 @@ impl Abi {
         symbol_name: String,
         info: RustCInfo,
     ) -> Result<Abi, LoadProcMacroDylibError> {
-        // FIXME: this should use exclusive ranges when they're stable
-        // https://github.com/rust-lang/rust/issues/37854
-        match (info.version.0, info.version.1) {
-            (1, 47..=54) => {
-                let inner = unsafe { Abi_1_47::from_lib(lib, symbol_name) }?;
-                Ok(Abi::Abi1_47(inner))
-            }
-            (1, 55..=55) => {
-                let inner = unsafe { Abi_1_55::from_lib(lib, symbol_name) }?;
-                Ok(Abi::Abi1_55(inner))
-            }
-            (1, 56..=57) => {
-                let inner = unsafe { Abi_1_56::from_lib(lib, symbol_name) }?;
-                Ok(Abi::Abi1_56(inner))
-            }
-            (1, 58..) => {
-                let inner = unsafe { Abi_1_58::from_lib(lib, symbol_name) }?;
-                Ok(Abi::Abi1_58(inner))
-            }
-            _ => Err(LoadProcMacroDylibError::UnsupportedABI),
+        if info.version.0 != 1 {
+            Err(LoadProcMacroDylibError::UnsupportedABI)
+        } else if info.version.1 < 47 {
+            Err(LoadProcMacroDylibError::UnsupportedABI)
+        } else if info.version.1 < 54 {
+            let inner = unsafe { Abi_1_47::from_lib(lib, symbol_name) }?;
+            Ok(Abi::Abi1_47(inner))
+        } else if info.version.1 < 56 {
+            let inner = unsafe { Abi_1_55::from_lib(lib, symbol_name) }?;
+            Ok(Abi::Abi1_55(inner))
+        } else if info.version.1 < 57 {
+            let inner = unsafe { Abi_1_56::from_lib(lib, symbol_name) }?;
+            Ok(Abi::Abi1_56(inner))
+        } else {
+            let inner = unsafe { Abi_1_58::from_lib(lib, symbol_name) }?;
+            Ok(Abi::Abi1_58(inner))
         }
     }
 


Test patch:
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index 5db6fd7974..2aa54fc33f 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/crates/ide/src/hover/tests.rs
@@ -173,7 +173,7 @@ m!(ab$0c);
             ---
 
             Outer
-        "#]],
+            "#]],
     );
 }
 
@@ -503,52 +503,30 @@ fn hover_const_static() {
     check(
         r#"const foo$0: u32 = 123;"#,
         expect![[r#"
-            *foo*
-
-            ```rust
-            test
-            ```
-
-            ```rust
-            const foo: u32 = 123
-            ```
-        "#]],
-    );
-    check(
-        r#"
-const foo$0: u32 = {
-    let x = foo();
-    x + 100
-};"#,
-        expect![[r#"
-            *foo*
+                *foo*
 
-            ```rust
-            test
-            ```
+                ```rust
+                test
+                ```
 
-            ```rust
-            const foo: u32 = {
-                let x = foo();
-                x + 100
-            }
-            ```
-        "#]],
+                ```rust
+                const foo: u32
+                ```
+            "#]],
     );
-
     check(
         r#"static foo$0: u32 = 456;"#,
         expect![[r#"
-            *foo*
+                *foo*
 
-            ```rust
-            test
-            ```
+                ```rust
+                test
+                ```
 
-            ```rust
-            static foo: u32 = 456
-            ```
-        "#]],
+                ```rust
+                static foo: u32
+                ```
+            "#]],
     );
 }
 
@@ -810,16 +788,16 @@ fn main() {
 }
 "#,
         expect![[r#"
-            *C*
+                *C*
 
-            ```rust
-            test
-            ```
+                ```rust
+                test
+                ```
 
-            ```rust
-            const C: u32 = 1
-            ```
-        "#]],
+                ```rust
+                const C: u32
+                ```
+            "#]],
     )
 }
 
@@ -1135,39 +1113,6 @@ fn foo() {
     );
 }
 
-#[test]
-fn test_hover_multiple_actions() {
-    check_actions(
-        r#"
-struct Bar;
-struct Foo { bar: Bar }
-
-fn foo(Foo { b$0ar }: &Foo) {}
-        "#,
-        expect![[r#"
-            [
-                GoToType(
-                    [
-                        HoverGotoTypeData {
-                            mod_path: "test::Bar",
-                            nav: NavigationTarget {
-                                file_id: FileId(
-                                    0,
-                                ),
-                                full_range: 0..11,
-                                focus_range: 7..10,
-                                name: "Bar",
-                                kind: Struct,
-                                description: "struct Bar",
-                            },
-                        },
-                    ],
-                ),
-            ]
-        "#]],
-    )
-}
-
 #[test]
 fn test_hover_through_literal_string_in_builtin_macro() {
     check_hover_no_result(
@@ -1751,40 +1696,40 @@ fn test_hover_test_has_action() {
 fn foo_$0test() {}
 "#,
         expect![[r#"
-            [
-                Reference(
-                    FilePosition {
-                        file_id: FileId(
-                            0,
-                        ),
-                        offset: 11,
-                    },
-                ),
-                Runnable(
-                    Runnable {
-                        use_name_in_title: false,
-                        nav: NavigationTarget {
+                [
+                    Reference(
+                        FilePosition {
                             file_id: FileId(
                                 0,
                             ),
-                            full_range: 0..24,
-                            focus_range: 11..19,
-                            name: "foo_test",
-                            kind: Function,
+                            offset: 11,
                         },
-                        kind: Test {
-                            test_id: Path(
-                                "foo_test",
-                            ),
-                            attr: TestAttr {
-                                ignore: false,
+                    ),
+                    Runnable(
+                        Runnable {
+                            use_name_in_title: false,
+                            nav: NavigationTarget {
+                                file_id: FileId(
+                                    0,
+                                ),
+                                full_range: 0..24,
+                                focus_range: 11..19,
+                                name: "foo_test",
+                                kind: Function,
                             },
+                            kind: Test {
+                                test_id: Path(
+                                    "foo_test",
+                                ),
+                                attr: TestAttr {
+                                    ignore: false,
+                                },
+                            },
+                            cfg: None,
                         },
-                        cfg: None,
-                    },
-                ),
-            ]
-        "#]],
+                    ),
+                ]
+            "#]],
     );
 }
 
@@ -2779,21 +2724,21 @@ fn main() {
 }
 "#,
         expect![[r#"
-            *f*
+                *f*
 
-            ```rust
-            f: &i32
-            ```
-            ---
+                ```rust
+                f: &i32
+                ```
+                ---
 
-            ```rust
-            test::S
-            ```
+                ```rust
+                test::S
+                ```
 
-            ```rust
-            f: i32
-            ```
-        "#]],
+                ```rust
+                f: i32
+                ```
+            "#]],
     );
 }
 
@@ -3231,20 +3176,20 @@ fn foo() {
 }
 "#,
         expect![[r#"
-            *FOO*
+                *FOO*
 
-            ```rust
-            test
-            ```
+                ```rust
+                test
+                ```
 
-            ```rust
-            const FOO: usize = 3
-            ```
+                ```rust
+                const FOO: usize
+                ```
 
-            ---
+                ---
 
-            This is a doc
-        "#]],
+                This is a doc
+            "#]],
     );
 }
 
diff --git a/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rast b/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rast
index 0eb5af54b8..5d5803f751 100644
--- a/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rast
@@ -1,5 +1,5 @@
-SOURCE_FILE@0..307
-  FN@0..306
+SOURCE_FILE@0..223
+  FN@0..222
     FN_KW@0..2 "fn"
     WHITESPACE@2..3 " "
     NAME@3..7
@@ -8,8 +8,8 @@ SOURCE_FILE@0..307
       L_PAREN@7..8 "("
       R_PAREN@8..9 ")"
     WHITESPACE@9..10 " "
-    BLOCK_EXPR@10..306
-      STMT_LIST@10..306
+    BLOCK_EXPR@10..222
+      STMT_LIST@10..222
         L_CURLY@10..11 "{"
         WHITESPACE@11..16 "\n    "
         EXPR_STMT@16..132
@@ -96,156 +96,80 @@ SOURCE_FILE@0..307
               WHITESPACE@126..131 "\n    "
               R_CURLY@131..132 "}"
         WHITESPACE@132..138 "\n\n    "
-        EXPR_STMT@138..220
-          MATCH_EXPR@138..220
-            MATCH_KW@138..143 "match"
-            WHITESPACE@143..144 " "
-            CALL_EXPR@144..158
-              PATH_EXPR@144..148
-                PATH@144..148
-                  PATH_SEGMENT@144..148
-                    NAME_REF@144..148
-                      IDENT@144..148 "Some"
-              ARG_LIST@148..158
-                L_PAREN@148..149 "("
-                CAST_EXPR@149..157
-                  LITERAL@149..151
-                    INT_NUMBER@149..151 "10"
-                  WHITESPACE@151..152 " "
-                  AS_KW@152..154 "as"
-                  WHITESPACE@154..155 " "
-                  PATH_TYPE@155..157
-                    PATH@155..157
-                      PATH_SEGMENT@155..157
-                        NAME_REF@155..157
-                          IDENT@155..157 "u8"
-                R_PAREN@157..158 ")"
-            WHITESPACE@158..159 " "
-            MATCH_ARM_LIST@159..220
-              L_CURLY@159..160 "{"
-              WHITESPACE@160..169 "\n        "
-              MATCH_ARM@169..190
-                OR_PAT@169..183
-                  TUPLE_STRUCT_PAT@169..176
-                    PATH@169..173
-                      PATH_SEGMENT@169..173
-                        NAME_REF@169..173
-                          IDENT@169..173 "Some"
-                    L_PAREN@173..174 "("
-                    LITERAL_PAT@174..175
-                      LITERAL@174..175
-                        INT_NUMBER@174..175 "0"
-                    R_PAREN@175..176 ")"
-                  WHITESPACE@176..177 " "
-                  PIPE@177..178 "|"
-                  WHITESPACE@178..179 " "
-                  IDENT_PAT@179..183
-                    NAME@179..183
-                      IDENT@179..183 "None"
-                WHITESPACE@183..184 " "
-                FAT_ARROW@184..186 "=>"
-                WHITESPACE@186..187 " "
-                TUPLE_EXPR@187..189
-                  L_PAREN@187..188 "("
-                  R_PAREN@188..189 ")"
-                COMMA@189..190 ","
-              WHITESPACE@190..199 "\n        "
-              MATCH_ARM@199..214
-                TUPLE_STRUCT_PAT@199..208
-                  PATH@199..203
-                    PATH_SEGMENT@199..203
-                      NAME_REF@199..203
-                        IDENT@199..203 "Some"
-                  L_PAREN@203..204 "("
-                  RANGE_PAT@204..207
-                    LITERAL_PAT@204..205
-                      LITERAL@204..205
-                        INT_NUMBER@204..205 "1"
-                    DOT2@205..207 ".."
-                  R_PAREN@207..208 ")"
-                WHITESPACE@208..209 " "
-                FAT_ARROW@209..211 "=>"
-                WHITESPACE@211..212 " "
-                TUPLE_EXPR@212..214
-                  L_PAREN@212..213 "("
-                  R_PAREN@213..214 ")"
-              WHITESPACE@214..219 "\n    "
-              R_CURLY@219..220 "}"
-        WHITESPACE@220..226 "\n\n    "
-        MATCH_EXPR@226..304
-          MATCH_KW@226..231 "match"
-          WHITESPACE@231..232 " "
-          TUPLE_EXPR@232..251
-            L_PAREN@232..233 "("
-            CAST_EXPR@233..241
-              LITERAL@233..235
-                INT_NUMBER@233..235 "10"
-              WHITESPACE@235..236 " "
-              AS_KW@236..238 "as"
-              WHITESPACE@238..239 " "
-              PATH_TYPE@239..241
-                PATH@239..241
-                  PATH_SEGMENT@239..241
-                    NAME_REF@239..241
-                      IDENT@239..241 "u8"
-            COMMA@241..242 ","
-            WHITESPACE@242..243 " "
-            CAST_EXPR@243..250
-              LITERAL@243..244
-                INT_NUMBER@243..244 "5"
-              WHITESPACE@244..245 " "
-              AS_KW@245..247 "as"
-              WHITESPACE@247..248 " "
-              PATH_TYPE@248..250
-                PATH@248..250
-                  PATH_SEGMENT@248..250
-                    NAME_REF@248..250
-                      IDENT@248..250 "u8"
-            R_PAREN@250..251 ")"
-          WHITESPACE@251..252 " "
-          MATCH_ARM_LIST@252..304
-            L_CURLY@252..253 "{"
-            WHITESPACE@253..262 "\n        "
-            MATCH_ARM@262..275
-              TUPLE_PAT@262..268
-                L_PAREN@262..263 "("
-                LITERAL_PAT@263..264
-                  LITERAL@263..264
-                    INT_NUMBER@263..264 "0"
-                COMMA@264..265 ","
-                WHITESPACE@265..266 " "
-                WILDCARD_PAT@266..267
-                  UNDERSCORE@266..267 "_"
-                R_PAREN@267..268 ")"
-              WHITESPACE@268..269 " "
-              FAT_ARROW@269..271 "=>"
-              WHITESPACE@271..272 " "
-              TUPLE_EXPR@272..274
-                L_PAREN@272..273 "("
-                R_PAREN@273..274 ")"
-              COMMA@274..275 ","
-            WHITESPACE@275..284 "\n        "
-            MATCH_ARM@284..298
-              TUPLE_PAT@284..292
-                L_PAREN@284..285 "("
-                RANGE_PAT@285..288
-                  LITERAL_PAT@285..286
-                    LITERAL@285..286
-                      INT_NUMBER@285..286 "1"
-                  DOT2@286..288 ".."
-                COMMA@288..289 ","
-                WHITESPACE@289..290 " "
-                WILDCARD_PAT@290..291
-                  UNDERSCORE@290..291 "_"
-                R_PAREN@291..292 ")"
-              WHITESPACE@292..293 " "
-              FAT_ARROW@293..295 "=>"
-              WHITESPACE@295..296 " "
-              TUPLE_EXPR@296..298
-                L_PAREN@296..297 "("
-                R_PAREN@297..298 ")"
-            WHITESPACE@298..303 "\n    "
-            R_CURLY@303..304 "}"
-        WHITESPACE@304..305 "\n"
-        R_CURLY@305..306 "}"
-  WHITESPACE@306..307 "\n"
+        MATCH_EXPR@138..220
+          MATCH_KW@138..143 "match"
+          WHITESPACE@143..144 " "
+          CALL_EXPR@144..158
+            PATH_EXPR@144..148
+              PATH@144..148
+                PATH_SEGMENT@144..148
+                  NAME_REF@144..148
+                    IDENT@144..148 "Some"
+            ARG_LIST@148..158
+              L_PAREN@148..149 "("
+              CAST_EXPR@149..157
+                LITERAL@149..151
+                  INT_NUMBER@149..151 "10"
+                WHITESPACE@151..152 " "
+                AS_KW@152..154 "as"
+                WHITESPACE@154..155 " "
+                PATH_TYPE@155..157
+                  PATH@155..157
+                    PATH_SEGMENT@155..157
+                      NAME_REF@155..157
+                        IDENT@155..157 "u8"
+              R_PAREN@157..158 ")"
+          WHITESPACE@158..159 " "
+          MATCH_ARM_LIST@159..220
+            L_CURLY@159..160 "{"
+            WHITESPACE@160..169 "\n        "
+            MATCH_ARM@169..190
+              OR_PAT@169..183
+                TUPLE_STRUCT_PAT@169..176
+                  PATH@169..173
+                    PATH_SEGMENT@169..173
+                      NAME_REF@169..173
+                        IDENT@169..173 "Some"
+                  L_PAREN@173..174 "("
+                  LITERAL_PAT@174..175
+                    LITERAL@174..175
+                      INT_NUMBER@174..175 "0"
+                  R_PAREN@175..176 ")"
+                WHITESPACE@176..177 " "
+                PIPE@177..178 "|"
+                WHITESPACE@178..179 " "
+                IDENT_PAT@179..183
+                  NAME@179..183
+                    IDENT@179..183 "None"
+              WHITESPACE@183..184 " "
+              FAT_ARROW@184..186 "=>"
+              WHITESPACE@186..187 " "
+              TUPLE_EXPR@187..189
+                L_PAREN@187..188 "("
+                R_PAREN@188..189 ")"
+              COMMA@189..190 ","
+            WHITESPACE@190..199 "\n        "
+            MATCH_ARM@199..214
+              TUPLE_STRUCT_PAT@199..208
+                PATH@199..203
+                  PATH_SEGMENT@199..203
+                    NAME_REF@199..203
+                      IDENT@199..203 "Some"
+                L_PAREN@203..204 "("
+                RANGE_PAT@204..207
+                  LITERAL_PAT@204..205
+                    LITERAL@204..205
+                      INT_NUMBER@204..205 "1"
+                  DOT2@205..207 ".."
+                R_PAREN@207..208 ")"
+              WHITESPACE@208..209 " "
+              FAT_ARROW@209..211 "=>"
+              WHITESPACE@211..212 " "
+              TUPLE_EXPR@212..214
+                L_PAREN@212..213 "("
+                R_PAREN@213..214 ")"
+            WHITESPACE@214..219 "\n    "
+            R_CURLY@219..220 "}"
+        WHITESPACE@220..221 "\n"
+        R_CURLY@221..222 "}"
+  WHITESPACE@222..223 "\n"
diff --git a/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rs b/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rs
index 6c586a8956..fa91efd212 100644
--- a/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rs
+++ b/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rs
@@ -10,9 +10,4 @@ fn main() {
         Some(0) | None => (),
         Some(1..) => ()
     }
-
-    match (10 as u8, 5 as u8) {
-        (0, _) => (),
-        (1.., _) => ()
-    }
 }