Repository: rust-lang/rust-analyzer
Pull request #19086 (2025-02-03 13:43:39)

fix: Fix some mir eval/lowerings
Was attempting to get our debug printing in hover working but our mir infra seems to be just really broken, we get far enough that we do an invalid stack write now in some closure but I have no idea why. We should really clean up the mir infra.


Patch:
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index 2ccdc8c042..651502965e 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -14,3 +14,4 @@ f247090558c9ba3c551566eae5882b7ca865225f
 b2f6fd4f961fc7e4fbfdb80cae2e6065f8436f15
 c48062fe2ab9a2d913d1985a6b0aec4bf936bfc1
 f532576ac53ddcc666bc8d59e0b6437065e2f599
+4704881b641884de50645637108b6b6f5b68aaf9
diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs
index e83ce6dc42..166e00c9d2 100644
--- a/crates/hir-def/src/lang_item.rs
+++ b/crates/hir-def/src/lang_item.rs
@@ -501,4 +501,5 @@ language_item_table! {
 
     String,                  sym::String,              string,                     Target::Struct,         GenericRequirement::None;
     CStr,                    sym::CStr,                c_str,                      Target::Struct,         GenericRequirement::None;
+    Ordering,                sym::Ordering,            ordering,                   Target::Enum,           GenericRequirement::None;
 }
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 8e4c4db102..6b20522cf3 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -1644,14 +1644,15 @@ impl Evaluator<'_> {
             Variants::Multiple { tag, tag_encoding, variants, .. } => {
                 let size = tag.size(&*self.target_data_layout).bytes_usize();
                 let offset = layout.fields.offset(0).bytes_usize(); // The only field on enum variants is the tag field
+                let is_signed = tag.is_signed();
                 match tag_encoding {
                     TagEncoding::Direct => {
                         let tag = &bytes[offset..offset + size];
-                        Ok(i128::from_le_bytes(pad16(tag, false)))
+                        Ok(i128::from_le_bytes(pad16(tag, is_signed)))
                     }
                     TagEncoding::Niche { untagged_variant, niche_start, .. } => {
                         let tag = &bytes[offset..offset + size];
-                        let candidate_tag = i128::from_le_bytes(pad16(tag, false))
+                        let candidate_tag = i128::from_le_bytes(pad16(tag, is_signed))
                             .wrapping_sub(*niche_start as i128)
                             as usize;
                         let idx = variants
@@ -2943,10 +2944,10 @@ pub fn render_const_using_debug_impl(
     // a3 = ::core::fmt::Arguments::new_v1(a1, a2)
     // FIXME: similarly, we should call function here, not directly working with memory.
     let a3 = evaluator.heap_allocate(evaluator.ptr_size() * 6, evaluator.ptr_size())?;
-    evaluator.write_memory(a3.offset(2 * evaluator.ptr_size()), &a1.to_bytes())?;
+    evaluator.write_memory(a3, &a1.to_bytes())?;
+    evaluator.write_memory(a3.offset(evaluator.ptr_size()), &[1])?;
+    evaluator.write_memory(a3.offset(2 * evaluator.ptr_size()), &a2.to_bytes())?;
     evaluator.write_memory(a3.offset(3 * evaluator.ptr_size()), &[1])?;
-    evaluator.write_memory(a3.offset(4 * evaluator.ptr_size()), &a2.to_bytes())?;
-    evaluator.write_memory(a3.offset(5 * evaluator.ptr_size()), &[1])?;
     let Some(ValueNs::FunctionId(format_fn)) = resolver.resolve_path_in_value_ns_fully(
         db.upcast(),
         &hir_def::path::Path::from_known_path_with_no_generic(path![std::fmt::format]),
diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs
index 0a78f4a5b2..38b189a517 100644
--- a/crates/hir-ty/src/mir/eval/shim.rs
+++ b/crates/hir-ty/src/mir/eval/shim.rs
@@ -1,11 +1,12 @@
 //! Interpret intrinsics, lang items and `extern "C"` wellknown functions which their implementation
 //! is not available.
 //!
-use std::cmp;
+use std::cmp::{self, Ordering};
 
 use chalk_ir::TyKind;
 use hir_def::{
     builtin_type::{BuiltinInt, BuiltinUint},
+    lang_item::LangItemTarget,
     resolver::HasResolver,
 };
 use hir_expand::name::Name;
@@ -1317,6 +1318,82 @@ impl Evaluator<'_> {
                 self.write_memory_using_ref(dst, size)?.fill(val);
                 Ok(())
             }
+            "ptr_metadata" => {
+                let [ptr] = args else {
+                    return Err(MirEvalError::InternalError(
+                        "ptr_metadata args are not provided".into(),
+                    ));
+                };
+                let arg = ptr.interval.get(self)?.to_owned();
+                let metadata = &arg[self.ptr_size()..];
+                destination.write_from_bytes(self, metadata)?;
+                Ok(())
+            }
+            "three_way_compare" => {
+                let [lhs, rhs] = args else {
+                    return Err(MirEvalError::InternalError(
+                        "three_way_compare args are not provided".into(),
+                    ));
+                };
+                let Some(ty) =
+                    generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
+                else {
+                    return Err(MirEvalError::InternalError(
+                        "three_way_compare generic arg is not provided".into(),
+                    ));
+                };
+                let signed = match ty.as_builtin().unwrap() {
+                    BuiltinType::Int(_) => true,
+                    BuiltinType::Uint(_) => false,
+                    _ => {
+                        return Err(MirEvalError::InternalError(
+                            "three_way_compare expects an integral type".into(),
+                        ))
+                    }
+                };
+                let rhs = rhs.get(self)?;
+                let lhs = lhs.get(self)?;
+                let mut result = Ordering::Equal;
+                for (l, r) in lhs.iter().zip(rhs).rev() {
+                    let it = l.cmp(r);
+                    if it != Ordering::Equal {
+                        result = it;
+                        break;
+                    }
+                }
+                if signed {
+                    if let Some((&l, &r)) = lhs.iter().zip(rhs).next_back() {
+                        if l != r {
+                            result = (l as i8).cmp(&(r as i8));
+                        }
+                    }
+                }
+                if let Some(LangItemTarget::EnumId(e)) =
+                    self.db.lang_item(self.crate_id, LangItem::Ordering)
+                {
+                    let ty = self.db.ty(e.into());
+                    let r = self
+                        .compute_discriminant(ty.skip_binders().clone(), &[result as i8 as u8])?;
+                    destination.write_from_bytes(self, &r.to_le_bytes()[0..destination.size])?;
+                    Ok(())
+                } else {
+                    Err(MirEvalError::InternalError("Ordering enum not found".into()))
+                }
+            }
+            "aggregate_raw_ptr" => {
+                let [data, meta] = args else {
+                    return Err(MirEvalError::InternalError(
+                        "aggregate_raw_ptr args are not provided".into(),
+                    ));
+                };
+                destination.write_from_interval(self, data.interval)?;
+                Interval {
+                    addr: destination.addr.offset(data.interval.size),
+                    size: destination.size - data.interval.size,
+                }
+                .write_from_interval(self, meta.interval)?;
+                Ok(())
+            }
             _ if needs_override => not_supported!("intrinsic {name} is not implemented"),
             _ => return Ok(false),
         }
diff --git a/crates/ide/src/moniker.rs b/crates/ide/src/moniker.rs
index 66ea49a98a..d97c12ebaf 100644
--- a/crates/ide/src/moniker.rs
+++ b/crates/ide/src/moniker.rs
@@ -289,10 +289,7 @@ fn def_to_non_local_moniker(
     definition: Definition,
     from_crate: Crate,
 ) -> Option<Moniker> {
-    let module = match definition {
-        Definition::Module(module) if module.is_crate_root() => module,
-        _ => definition.module(db)?,
-    };
+    let module = definition.module(db)?;
     let krate = module.krate();
     let edition = krate.edition(db);
 
@@ -325,18 +322,12 @@ fn def_to_non_local_moniker(
                         name: name.display(db, edition).to_string(),
                         desc: def_to_kind(db, def).into(),
                     });
+                } else if reverse_description.is_empty() {
+                    // Don't allow the last descriptor to be absent.
+                    return None;
                 } else {
                     match def {
-                        Definition::Module(module) if module.is_crate_root() => {
-                            // only include `crate` namespace by itself because we prefer
-                            // `rust-analyzer cargo foo . bar/` over `rust-analyzer cargo foo . crate/bar/`
-                            if reverse_description.is_empty() {
-                                reverse_description.push(MonikerDescriptor {
-                                    name: "crate".to_owned(),
-                                    desc: MonikerDescriptorKind::Namespace,
-                                });
-                            }
-                        }
+                        Definition::Module(module) if module.is_crate_root() => {}
                         _ => {
                             tracing::error!(?def, "Encountered enclosing definition with no name");
                         }
@@ -349,9 +340,6 @@ fn def_to_non_local_moniker(
         };
         def = next_def;
     }
-    if reverse_description.is_empty() {
-        return None;
-    }
     reverse_description.reverse();
     let description = reverse_description;
 
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs
index 3121bb7a8e..8050a38b3c 100644
--- a/crates/ide/src/static_index.rs
+++ b/crates/ide/src/static_index.rs
@@ -169,10 +169,10 @@ impl StaticIndex<'_> {
             .unwrap();
         // hovers
         let sema = hir::Semantics::new(self.db);
-        let root = sema.parse_guess_edition(file_id).syntax().clone();
+        let tokens_or_nodes = sema.parse_guess_edition(file_id).syntax().clone();
         let edition =
             sema.attach_first_edition(file_id).map(|it| it.edition()).unwrap_or(Edition::CURRENT);
-        let tokens = root.descendants_with_tokens().filter_map(|it| match it {
+        let tokens = tokens_or_nodes.descendants_with_tokens().filter_map(|it| match it {
             syntax::NodeOrToken::Node(_) => None,
             syntax::NodeOrToken::Token(it) => Some(it),
         });
@@ -194,19 +194,24 @@ impl StaticIndex<'_> {
             )
         });
         let mut result = StaticIndexedFile { file_id, inlay_hints, folds, tokens: vec![] };
-
-        let mut add_token = |def: Definition, range: TextRange, scope_node: &SyntaxNode| {
+        for token in tokens {
+            let range = token.text_range();
+            let node = token.parent().unwrap();
+            let def = match get_definition(&sema, token.clone()) {
+                Some(it) => it,
+                None => continue,
+            };
             let id = if let Some(it) = self.def_map.get(&def) {
                 *it
             } else {
                 let it = self.tokens.insert(TokenStaticData {
-                    documentation: documentation_for_definition(&sema, def, scope_node),
+                    documentation: documentation_for_definition(&sema, def, &node),
                     hover: Some(hover_for_definition(
                         &sema,
                         file_id,
                         def,
                         None,
-                        scope_node,
+                        &node,
                         None,
                         false,
                         &hover_config,
@@ -235,22 +240,6 @@ impl StaticIndex<'_> {
                 },
             });
             result.tokens.push((range, id));
-        };
-
-        if let Some(module) = sema.file_to_module_def(file_id) {
-            let def = Definition::Module(module);
-            let range = root.text_range();
-            add_token(def, range, &root);
-        }
-
-        for token in tokens {
-            let range = token.text_range();
-            let node = token.parent().unwrap();
-            let def = match get_definition(&sema, token.clone()) {
-                Some(it) => it,
-                None => continue,
-            };
-            add_token(def, range, &node);
         }
         self.files.push(result);
     }
@@ -311,10 +300,6 @@ mod tests {
         let mut range_set: FxHashSet<_> = ranges.iter().map(|it| it.0).collect();
         for f in s.files {
             for (range, _) in f.tokens {
-                if range.start() == TextSize::from(0) {
-                    // ignore whole file range corresponding to module definition
-                    continue;
-                }
                 let it = FileRange { file_id: f.file_id, range };
                 if !range_set.contains(&it) {
                     panic!("additional range {it:?}");
diff --git a/crates/intern/src/symbol/symbols.rs b/crates/intern/src/symbol/symbols.rs
index 1b543ddf81..8df7c59aa7 100644
--- a/crates/intern/src/symbol/symbols.rs
+++ b/crates/intern/src/symbol/symbols.rs
@@ -347,6 +347,7 @@ define_symbols! {
     option,
     Option,
     Ord,
+    Ordering,
     Output,
     CallRefFuture,
     CallOnceFuture,
diff --git a/crates/rust-analyzer/src/cli/scip.rs b/crates/rust-analyzer/src/cli/scip.rs
index ee7b698975..dc0f722aae 100644
--- a/crates/rust-analyzer/src/cli/scip.rs
+++ b/crates/rust-analyzer/src/cli/scip.rs
@@ -444,14 +444,14 @@ impl SymbolGenerator {
                     MonikerResult::Moniker(moniker) => TokenSymbols {
                         symbol: scip::symbol::format_symbol(moniker_to_symbol(moniker)),
                         enclosing_symbol: None,
-                        is_inherent_impl: match &moniker.identifier.description[..] {
-                            // inherent impls are represented as impl#[SelfType]
-                            [.., descriptor, _] => {
+                        is_inherent_impl: moniker
+                            .identifier
+                            .description
+                            .get(moniker.identifier.description.len() - 2)
+                            .is_some_and(|descriptor| {
                                 descriptor.desc == MonikerDescriptorKind::Type
                                     && descriptor.name == "impl"
-                            }
-                            _ => false,
-                        },
+                            }),
                     },
                     MonikerResult::Local { enclosing_moniker } => {
                         let local_symbol = scip::types::Symbol::new_local(local_count);
@@ -549,9 +549,7 @@ mod test {
                 continue;
             }
             for &(range, id) in &file.tokens {
-                // check if cursor is within token, ignoring token for the module defined by the file (whose range is the whole file)
-                if range.start() != TextSize::from(0) && range.contains(offset - TextSize::from(1))
-                {
+                if range.contains(offset - TextSize::from(1)) {
                     let token = si.tokens.get(id).unwrap();
                     found_symbol = match token.moniker.as_ref() {
                         None => None,
@@ -887,7 +885,7 @@ pub mod example_mod {
         );
 
         let file = si.files.first().unwrap();
-        let (_, token_id) = file.tokens.get(1).unwrap(); // first token is file module, second is `bar`
+        let (_, token_id) = file.tokens.first().unwrap();
         let token = si.tokens.get(*token_id).unwrap();
 
         assert_eq!(token.documentation.as_ref().map(|d| d.as_str()), Some("foo"));
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index b52f64aaac..0f2d7823b7 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -396,7 +396,6 @@ impl GlobalState {
             || !self.config.same_source_root_parent_map(&self.local_roots_parent_map)
         {
             let config_change = {
-                let _p = span!(Level::INFO, "GlobalState::process_changes/config_change").entered();
                 let user_config_path = (|| {
                     let mut p = Config::user_config_dir_path()?;
                     p.push("rust-analyzer.toml");
@@ -570,12 +569,12 @@ impl GlobalState {
         if let Some((method, start)) = self.req_queue.incoming.complete(&response.id) {
             if let Some(err) = &response.error {
                 if err.message.starts_with("server panicked") {
-                    self.poke_rust_analyzer_developer(format!("{}, check the log", err.message));
+                    self.poke_rust_analyzer_developer(format!("{}, check the log", err.message))
                 }
             }
 
             let duration = start.elapsed();
-            tracing::debug!(name: "message response", method, %response.id, duration = format_args!("{:0.2?}", duration));
+            tracing::debug!("handled {} - ({}) in {:0.2?}", method, response.id, duration);
             self.send(response.into());
         }
     }
diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs
index 48856d19e1..84ba89d9f3 100644
--- a/crates/rust-analyzer/src/handlers/notification.rs
+++ b/crates/rust-analyzer/src/handlers/notification.rs
@@ -74,8 +74,7 @@ pub(crate) fn handle_did_open_text_document(
             tracing::error!("duplicate DidOpenTextDocument: {}", path);
         }
 
-        let contents = params.text_document.text.into_bytes();
-        state.vfs.write().0.set_file_contents(path, Some(contents));
+        state.vfs.write().0.set_file_contents(path, Some(params.text_document.text.into_bytes()));
         if state.config.discover_workspace_config().is_some() {
             tracing::debug!("queuing task");
             let _ = state
diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs
index ed028f1d37..39cbf53eaa 100644
--- a/crates/rust-analyzer/src/handlers/request.rs
+++ b/crates/rust-analyzer/src/handlers/request.rs
@@ -2318,21 +2318,18 @@ fn run_rustfmt(
         }
     };
 
-    let output = {
-        let _p = tracing::info_span!("rustfmt", ?command).entered();
+    tracing::debug!(?command, "created format command");
 
-        let mut rustfmt = command
-            .stdin(Stdio::piped())
-            .stdout(Stdio::piped())
-            .stderr(Stdio::piped())
-            .spawn()
-            .context(format!("Failed to spawn {command:?}"))?;
+    let mut rustfmt = command
+        .stdin(Stdio::piped())
+        .stdout(Stdio::piped())
+        .stderr(Stdio::piped())
+        .spawn()
+        .context(format!("Failed to spawn {command:?}"))?;
 
-        rustfmt.stdin.as_mut().unwrap().write_all(file.as_bytes())?;
-
-        rustfmt.wait_with_output()?
-    };
+    rustfmt.stdin.as_mut().unwrap().write_all(file.as_bytes())?;
 
+    let output = rustfmt.wait_with_output()?;
     let captured_stdout = String::from_utf8(output.stdout)?;
     let captured_stderr = String::from_utf8(output.stderr).unwrap_or_default();
 
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index d18e577047..0add2cdf5a 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -701,7 +701,8 @@ impl GlobalState {
 
         let (crate_graph, proc_macro_paths, ws_data) = {
             // Create crate graph from all the workspaces
-            let vfs = &self.vfs.read().0;
+            let vfs = &mut self.vfs.write().0;
+
             let load = |path: &AbsPath| {
                 let vfs_path = vfs::VfsPath::from(path.to_path_buf());
                 self.crate_graph_file_dependencies.insert(vfs_path.clone());


Test patch:
diff --git a/crates/rust-analyzer/tests/slow-tests/cli.rs b/crates/rust-analyzer/tests/slow-tests/cli.rs
index 4ef930e985..fba5466691 100644
--- a/crates/rust-analyzer/tests/slow-tests/cli.rs
+++ b/crates/rust-analyzer/tests/slow-tests/cli.rs
@@ -43,93 +43,89 @@ mod tests {
     expect![[r#"
         {"id":2,"type":"vertex","label":"foldingRangeResult","result":[{"startLine":2,"startCharacter":43,"endLine":6,"endCharacter":1},{"startLine":3,"startCharacter":19,"endLine":5,"endCharacter":5},{"startLine":9,"startCharacter":10,"endLine":12,"endCharacter":1}]}
         {"id":3,"type":"edge","label":"textDocument/foldingRange","inV":2,"outV":1}
-        {"id":4,"type":"vertex","label":"range","start":{"line":0,"character":0},"end":{"line":13,"character":0}}
+        {"id":4,"type":"vertex","label":"range","start":{"line":0,"character":3},"end":{"line":0,"character":8}}
         {"id":5,"type":"vertex","label":"resultSet"}
         {"id":6,"type":"edge","label":"next","inV":5,"outV":4}
-        {"id":7,"type":"vertex","label":"range","start":{"line":0,"character":3},"end":{"line":0,"character":8}}
+        {"id":7,"type":"vertex","label":"range","start":{"line":2,"character":13},"end":{"line":2,"character":43}}
         {"id":8,"type":"vertex","label":"resultSet"}
         {"id":9,"type":"edge","label":"next","inV":8,"outV":7}
-        {"id":10,"type":"vertex","label":"range","start":{"line":2,"character":13},"end":{"line":2,"character":43}}
-        {"id":11,"type":"vertex","label":"resultSet"}
-        {"id":12,"type":"edge","label":"next","inV":11,"outV":10}
-        {"id":13,"type":"vertex","label":"range","start":{"line":8,"character":0},"end":{"line":8,"character":30}}
-        {"id":14,"type":"edge","label":"next","inV":11,"outV":13}
-        {"id":15,"type":"vertex","label":"range","start":{"line":8,"character":32},"end":{"line":8,"character":39}}
+        {"id":10,"type":"vertex","label":"range","start":{"line":8,"character":0},"end":{"line":8,"character":30}}
+        {"id":11,"type":"edge","label":"next","inV":8,"outV":10}
+        {"id":12,"type":"vertex","label":"range","start":{"line":8,"character":32},"end":{"line":8,"character":39}}
+        {"id":13,"type":"vertex","label":"resultSet"}
+        {"id":14,"type":"edge","label":"next","inV":13,"outV":12}
+        {"id":15,"type":"vertex","label":"range","start":{"line":9,"character":4},"end":{"line":9,"character":9}}
         {"id":16,"type":"vertex","label":"resultSet"}
         {"id":17,"type":"edge","label":"next","inV":16,"outV":15}
-        {"id":18,"type":"vertex","label":"range","start":{"line":9,"character":4},"end":{"line":9,"character":9}}
+        {"id":18,"type":"vertex","label":"range","start":{"line":10,"character":8},"end":{"line":10,"character":13}}
         {"id":19,"type":"vertex","label":"resultSet"}
         {"id":20,"type":"edge","label":"next","inV":19,"outV":18}
-        {"id":21,"type":"vertex","label":"range","start":{"line":10,"character":8},"end":{"line":10,"character":13}}
-        {"id":22,"type":"edge","label":"next","inV":5,"outV":21}
-        {"id":23,"type":"vertex","label":"range","start":{"line":11,"character":4},"end":{"line":11,"character":34}}
-        {"id":24,"type":"edge","label":"next","inV":11,"outV":23}
-        {"id":25,"type":"vertex","label":"range","start":{"line":11,"character":36},"end":{"line":11,"character":43}}
-        {"id":26,"type":"vertex","label":"resultSet"}
-        {"id":27,"type":"edge","label":"next","inV":26,"outV":25}
-        {"id":28,"type":"edge","label":"contains","inVs":[4,7,10,13,15,18,21,23,25],"outV":1}
-        {"id":29,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nextern crate foo\n```"}}}
-        {"id":30,"type":"edge","label":"textDocument/hover","inV":29,"outV":5}
-        {"id":31,"type":"vertex","label":"packageInformation","name":"foo","manager":"cargo","version":"0.0.0"}
-        {"id":32,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::crate","unique":"scheme","kind":"export"}
-        {"id":33,"type":"edge","label":"packageInformation","inV":31,"outV":32}
-        {"id":34,"type":"edge","label":"moniker","inV":32,"outV":5}
-        {"id":35,"type":"vertex","label":"definitionResult"}
-        {"id":36,"type":"edge","label":"item","document":1,"inVs":[4],"outV":35}
-        {"id":37,"type":"edge","label":"textDocument/definition","inV":35,"outV":5}
-        {"id":38,"type":"vertex","label":"referenceResult"}
-        {"id":39,"type":"edge","label":"textDocument/references","inV":38,"outV":5}
-        {"id":40,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[4],"outV":38}
-        {"id":41,"type":"edge","label":"item","document":1,"property":"references","inVs":[21],"outV":38}
-        {"id":42,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\n#[allow]\n```\n\n---\n\nValid forms are:\n\n* \\#\\[allow(lint1, lint2, ..., /\\*opt\\*/ reason = \"...\")\\]"}}}
-        {"id":43,"type":"edge","label":"textDocument/hover","inV":42,"outV":8}
-        {"id":44,"type":"vertex","label":"referenceResult"}
-        {"id":45,"type":"edge","label":"textDocument/references","inV":44,"outV":8}
-        {"id":46,"type":"edge","label":"item","document":1,"property":"references","inVs":[7],"outV":44}
-        {"id":47,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nmacro_rules! generate_const_from_identifier\n```"}}}
-        {"id":48,"type":"edge","label":"textDocument/hover","inV":47,"outV":11}
-        {"id":49,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::generate_const_from_identifier","unique":"scheme","kind":"export"}
-        {"id":50,"type":"edge","label":"packageInformation","inV":31,"outV":49}
-        {"id":51,"type":"edge","label":"moniker","inV":49,"outV":11}
-        {"id":52,"type":"vertex","label":"definitionResult"}
-        {"id":53,"type":"edge","label":"item","document":1,"inVs":[10],"outV":52}
-        {"id":54,"type":"edge","label":"textDocument/definition","inV":52,"outV":11}
-        {"id":55,"type":"vertex","label":"referenceResult"}
-        {"id":56,"type":"edge","label":"textDocument/references","inV":55,"outV":11}
-        {"id":57,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[10],"outV":55}
-        {"id":58,"type":"edge","label":"item","document":1,"property":"references","inVs":[13,23],"outV":55}
-        {"id":59,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nconst REQ_001: &str = \"encoded_data\"\n```"}}}
-        {"id":60,"type":"edge","label":"textDocument/hover","inV":59,"outV":16}
-        {"id":61,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::REQ_001","unique":"scheme","kind":"export"}
-        {"id":62,"type":"edge","label":"packageInformation","inV":31,"outV":61}
-        {"id":63,"type":"edge","label":"moniker","inV":61,"outV":16}
-        {"id":64,"type":"vertex","label":"definitionResult"}
-        {"id":65,"type":"edge","label":"item","document":1,"inVs":[15],"outV":64}
-        {"id":66,"type":"edge","label":"textDocument/definition","inV":64,"outV":16}
-        {"id":67,"type":"vertex","label":"referenceResult"}
-        {"id":68,"type":"edge","label":"textDocument/references","inV":67,"outV":16}
-        {"id":69,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[15],"outV":67}
-        {"id":70,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nmod tests\n```"}}}
-        {"id":71,"type":"edge","label":"textDocument/hover","inV":70,"outV":19}
-        {"id":72,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::tests","unique":"scheme","kind":"export"}
-        {"id":73,"type":"edge","label":"packageInformation","inV":31,"outV":72}
-        {"id":74,"type":"edge","label":"moniker","inV":72,"outV":19}
-        {"id":75,"type":"vertex","label":"definitionResult"}
-        {"id":76,"type":"edge","label":"item","document":1,"inVs":[18],"outV":75}
-        {"id":77,"type":"edge","label":"textDocument/definition","inV":75,"outV":19}
-        {"id":78,"type":"vertex","label":"referenceResult"}
-        {"id":79,"type":"edge","label":"textDocument/references","inV":78,"outV":19}
-        {"id":80,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[18],"outV":78}
-        {"id":81,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo::tests\n```\n\n```rust\nconst REQ_002: &str = \"encoded_data\"\n```"}}}
-        {"id":82,"type":"edge","label":"textDocument/hover","inV":81,"outV":26}
-        {"id":83,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::tests::REQ_002","unique":"scheme","kind":"export"}
-        {"id":84,"type":"edge","label":"packageInformation","inV":31,"outV":83}
-        {"id":85,"type":"edge","label":"moniker","inV":83,"outV":26}
-        {"id":86,"type":"vertex","label":"definitionResult"}
-        {"id":87,"type":"edge","label":"item","document":1,"inVs":[25],"outV":86}
-        {"id":88,"type":"edge","label":"textDocument/definition","inV":86,"outV":26}
-        {"id":89,"type":"vertex","label":"referenceResult"}
-        {"id":90,"type":"edge","label":"textDocument/references","inV":89,"outV":26}
-        {"id":91,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[25],"outV":89}
+        {"id":21,"type":"vertex","label":"range","start":{"line":11,"character":4},"end":{"line":11,"character":34}}
+        {"id":22,"type":"edge","label":"next","inV":8,"outV":21}
+        {"id":23,"type":"vertex","label":"range","start":{"line":11,"character":36},"end":{"line":11,"character":43}}
+        {"id":24,"type":"vertex","label":"resultSet"}
+        {"id":25,"type":"edge","label":"next","inV":24,"outV":23}
+        {"id":26,"type":"edge","label":"contains","inVs":[4,7,10,12,15,18,21,23],"outV":1}
+        {"id":27,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\n#[allow]\n```\n\n---\n\nValid forms are:\n\n* \\#\\[allow(lint1, lint2, ..., /\\*opt\\*/ reason = \"...\")\\]"}}}
+        {"id":28,"type":"edge","label":"textDocument/hover","inV":27,"outV":5}
+        {"id":29,"type":"vertex","label":"referenceResult"}
+        {"id":30,"type":"edge","label":"textDocument/references","inV":29,"outV":5}
+        {"id":31,"type":"edge","label":"item","document":1,"property":"references","inVs":[4],"outV":29}
+        {"id":32,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nmacro_rules! generate_const_from_identifier\n```"}}}
+        {"id":33,"type":"edge","label":"textDocument/hover","inV":32,"outV":8}
+        {"id":34,"type":"vertex","label":"packageInformation","name":"foo","manager":"cargo","version":"0.0.0"}
+        {"id":35,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::generate_const_from_identifier","unique":"scheme","kind":"export"}
+        {"id":36,"type":"edge","label":"packageInformation","inV":34,"outV":35}
+        {"id":37,"type":"edge","label":"moniker","inV":35,"outV":8}
+        {"id":38,"type":"vertex","label":"definitionResult"}
+        {"id":39,"type":"edge","label":"item","document":1,"inVs":[7],"outV":38}
+        {"id":40,"type":"edge","label":"textDocument/definition","inV":38,"outV":8}
+        {"id":41,"type":"vertex","label":"referenceResult"}
+        {"id":42,"type":"edge","label":"textDocument/references","inV":41,"outV":8}
+        {"id":43,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[7],"outV":41}
+        {"id":44,"type":"edge","label":"item","document":1,"property":"references","inVs":[10,21],"outV":41}
+        {"id":45,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nconst REQ_001: &str = \"encoded_data\"\n```"}}}
+        {"id":46,"type":"edge","label":"textDocument/hover","inV":45,"outV":13}
+        {"id":47,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::REQ_001","unique":"scheme","kind":"export"}
+        {"id":48,"type":"edge","label":"packageInformation","inV":34,"outV":47}
+        {"id":49,"type":"edge","label":"moniker","inV":47,"outV":13}
+        {"id":50,"type":"vertex","label":"definitionResult"}
+        {"id":51,"type":"edge","label":"item","document":1,"inVs":[12],"outV":50}
+        {"id":52,"type":"edge","label":"textDocument/definition","inV":50,"outV":13}
+        {"id":53,"type":"vertex","label":"referenceResult"}
+        {"id":54,"type":"edge","label":"textDocument/references","inV":53,"outV":13}
+        {"id":55,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[12],"outV":53}
+        {"id":56,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nmod tests\n```"}}}
+        {"id":57,"type":"edge","label":"textDocument/hover","inV":56,"outV":16}
+        {"id":58,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::tests","unique":"scheme","kind":"export"}
+        {"id":59,"type":"edge","label":"packageInformation","inV":34,"outV":58}
+        {"id":60,"type":"edge","label":"moniker","inV":58,"outV":16}
+        {"id":61,"type":"vertex","label":"definitionResult"}
+        {"id":62,"type":"edge","label":"item","document":1,"inVs":[15],"outV":61}
+        {"id":63,"type":"edge","label":"textDocument/definition","inV":61,"outV":16}
+        {"id":64,"type":"vertex","label":"referenceResult"}
+        {"id":65,"type":"edge","label":"textDocument/references","inV":64,"outV":16}
+        {"id":66,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[15],"outV":64}
+        {"id":67,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nextern crate foo\n```"}}}
+        {"id":68,"type":"edge","label":"textDocument/hover","inV":67,"outV":19}
+        {"id":69,"type":"vertex","label":"definitionResult"}
+        {"id":70,"type":"vertex","label":"range","start":{"line":0,"character":0},"end":{"line":13,"character":0}}
+        {"id":71,"type":"edge","label":"contains","inVs":[70],"outV":1}
+        {"id":72,"type":"edge","label":"item","document":1,"inVs":[70],"outV":69}
+        {"id":73,"type":"edge","label":"textDocument/definition","inV":69,"outV":19}
+        {"id":74,"type":"vertex","label":"referenceResult"}
+        {"id":75,"type":"edge","label":"textDocument/references","inV":74,"outV":19}
+        {"id":76,"type":"edge","label":"item","document":1,"property":"references","inVs":[18],"outV":74}
+        {"id":77,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo::tests\n```\n\n```rust\nconst REQ_002: &str = \"encoded_data\"\n```"}}}
+        {"id":78,"type":"edge","label":"textDocument/hover","inV":77,"outV":24}
+        {"id":79,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::tests::REQ_002","unique":"scheme","kind":"export"}
+        {"id":80,"type":"edge","label":"packageInformation","inV":34,"outV":79}
+        {"id":81,"type":"edge","label":"moniker","inV":79,"outV":24}
+        {"id":82,"type":"vertex","label":"definitionResult"}
+        {"id":83,"type":"edge","label":"item","document":1,"inVs":[23],"outV":82}
+        {"id":84,"type":"edge","label":"textDocument/definition","inV":82,"outV":24}
+        {"id":85,"type":"vertex","label":"referenceResult"}
+        {"id":86,"type":"edge","label":"textDocument/references","inV":85,"outV":24}
+        {"id":87,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[23],"outV":85}
     "#]].assert_eq(stdout);
 }