rubydex 0.2.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +69 -3
  3. data/THIRD_PARTY_LICENSES.html +34 -1
  4. data/exe/rdx +131 -55
  5. data/ext/rubydex/declaration.c +1 -1
  6. data/ext/rubydex/definition.c +32 -4
  7. data/ext/rubydex/graph.c +14 -3
  8. data/ext/rubydex/query.c +105 -0
  9. data/ext/rubydex/query.h +8 -0
  10. data/ext/rubydex/reference.c +60 -0
  11. data/ext/rubydex/rubydex.c +2 -0
  12. data/ext/rubydex/utils.c +12 -0
  13. data/ext/rubydex/utils.h +5 -0
  14. data/lib/rubydex/version.rb +1 -1
  15. data/rbi/rubydex.rbi +22 -0
  16. data/rust/Cargo.lock +7 -0
  17. data/rust/rubydex/Cargo.toml +1 -0
  18. data/rust/rubydex/benches/graph_memory.rs +22 -4
  19. data/rust/rubydex/src/compile_assertions.rs +15 -0
  20. data/rust/rubydex/src/diagnostic.rs +1 -1
  21. data/rust/rubydex/src/indexing/rbs_indexer.rs +14 -2
  22. data/rust/rubydex/src/indexing/ruby_indexer.rs +49 -58
  23. data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +72 -16
  24. data/rust/rubydex/src/main.rs +2 -124
  25. data/rust/rubydex/src/model/declaration.rs +0 -11
  26. data/rust/rubydex/src/model/definitions.rs +27 -26
  27. data/rust/rubydex/src/model/document.rs +43 -7
  28. data/rust/rubydex/src/model/graph.rs +40 -28
  29. data/rust/rubydex/src/model/id.rs +55 -0
  30. data/rust/rubydex/src/model/ids.rs +21 -9
  31. data/rust/rubydex/src/model/name.rs +35 -7
  32. data/rust/rubydex/src/model/references.rs +16 -13
  33. data/rust/rubydex/src/operation/ruby_builder.rs +48 -59
  34. data/rust/rubydex/src/query/cypher/schema.rs +790 -0
  35. data/rust/rubydex/src/query/cypher/schema_info.rs +161 -0
  36. data/rust/rubydex/src/query/cypher/tests.rs +228 -0
  37. data/rust/rubydex/src/query/cypher.rs +57 -0
  38. data/rust/rubydex/src/query.rs +2 -0
  39. data/rust/rubydex/src/resolution.rs +248 -227
  40. data/rust/rubydex/src/resolution_tests.rs +263 -65
  41. data/rust/rubydex-sys/src/declaration_api.rs +6 -3
  42. data/rust/rubydex-sys/src/definition_api.rs +27 -7
  43. data/rust/rubydex-sys/src/graph_api.rs +158 -14
  44. data/rust/rubydex-sys/src/reference_api.rs +58 -12
  45. metadata +8 -2
@@ -10,7 +10,6 @@ use crate::{
10
10
  assert_no_diagnostics, assert_no_members, assert_owner_eq, assert_singleton_class_eq,
11
11
  diagnostic::Rule,
12
12
  model::{declaration::Ancestors, ids::DeclarationId, name::NameRef},
13
- resolution::Resolver,
14
13
  test_utils::GraphTest,
15
14
  };
16
15
 
@@ -3097,13 +3096,14 @@ mod declaration_creation_tests {
3097
3096
  #[test]
3098
3097
  fn resolution_for_ambiguous_namespace_definitions() {
3099
3098
  // Like many examples of Ruby code that is ambiguous to static analysis, this example is ambiguous due to
3100
- // require order. If `foo.rb` is loaded first, then `Bar` doesn't exist, Ruby crashes and we should emit an
3101
- // error or warning for a non existing constant.
3099
+ // require order. If `a_qualified.rb` is loaded first, then `Bar` doesn't exist, Ruby crashes and we should
3100
+ // emit an error or warning for a non existing constant.
3102
3101
  //
3103
- // If `bar.rb` is loaded first, then `Bar` resolves to top level `Bar` and `Bar::Baz` is defined, completely
3104
- // escaping the `Foo` nesting.
3102
+ // If `z_parent.rb` is loaded first, then `Bar` resolves to top level `Bar` and `Bar::Baz` is defined,
3103
+ // completely escaping the `Foo` nesting. The URIs intentionally sort in the opposite order: name complexity
3104
+ // must take precedence over URI so the top level `Bar` is resolved before the qualified `Bar::Baz` definition.
3105
3105
  let mut context = graph_test();
3106
- context.index_uri("file:///foo.rb", {
3106
+ context.index_uri("file:///a_qualified.rb", {
3107
3107
  r"
3108
3108
  module Foo
3109
3109
  class Bar::Baz
@@ -3111,7 +3111,7 @@ mod declaration_creation_tests {
3111
3111
  end
3112
3112
  "
3113
3113
  });
3114
- context.index_uri("file:///bar.rb", {
3114
+ context.index_uri("file:///z_parent.rb", {
3115
3115
  r"
3116
3116
  module Bar
3117
3117
  end
@@ -3123,62 +3123,11 @@ mod declaration_creation_tests {
3123
3123
 
3124
3124
  assert_no_members!(context, "Foo");
3125
3125
  assert_owner_eq!(context, "Foo", "Object");
3126
+ assert_declaration_does_not_exist!(context, "Foo::Bar");
3126
3127
 
3127
3128
  assert_members_eq!(context, "Bar", ["Baz"]);
3128
3129
  assert_owner_eq!(context, "Bar", "Object");
3129
3130
  }
3130
-
3131
- #[test]
3132
- fn expected_name_depth_order() {
3133
- let mut context = graph_test();
3134
- context.index_uri("file:///foo.rb", {
3135
- r"
3136
- module Foo
3137
- module Bar
3138
- module Baz
3139
- end
3140
-
3141
- module ::Top
3142
- class AfterTop
3143
- end
3144
- end
3145
- end
3146
-
3147
- module Qux::Zip
3148
- module Zap
3149
- class Zop::Boop
3150
- end
3151
- end
3152
- end
3153
- end
3154
- "
3155
- });
3156
-
3157
- let depths = Resolver::compute_name_depths(context.graph().names());
3158
- let mut names = context
3159
- .graph()
3160
- .names()
3161
- .iter()
3162
- .filter(|(_, n)| {
3163
- !["Kernel", "BasicObject", "Object", "Module", "Class"]
3164
- .contains(&context.graph().strings().get(n.str()).unwrap().as_str())
3165
- })
3166
- .collect::<Vec<_>>();
3167
- assert_eq!(10, names.len());
3168
-
3169
- names.sort_by_key(|(id, _)| depths.get(id).unwrap());
3170
-
3171
- assert_eq!(
3172
- [
3173
- "Top", "Foo", "Bar", "Qux", "AfterTop", "Baz", "Zip", "Zap", "Zop", "Boop"
3174
- ],
3175
- names
3176
- .iter()
3177
- .map(|(_, n)| context.graph().strings().get(n.str()).unwrap().as_str())
3178
- .collect::<Vec<_>>()
3179
- .as_slice()
3180
- );
3181
- }
3182
3131
  }
3183
3132
 
3184
3133
  mod singleton_class_tests {
@@ -4535,6 +4484,7 @@ mod promotability_tests {
4535
4484
 
4536
4485
  context.resolve();
4537
4486
  assert_no_diagnostics!(&context);
4487
+ assert_declaration_kind_eq!(context, "Qux", "<TODO>");
4538
4488
  assert_declaration_exists!(context, "Qux::<Qux>");
4539
4489
  }
4540
4490
 
@@ -4570,9 +4520,8 @@ mod promotability_tests {
4570
4520
 
4571
4521
  #[test]
4572
4522
  fn promoted_constant_has_correct_ancestors() {
4573
- // When a promotable constant is auto-promoted via singleton class access, we conservatively
4574
- // promote to a module (not a class) since we don't know what the call returns.
4575
- // Modules don't inherit from Object.
4523
+ // When a promotable constant is auto-promoted via singleton class access, its kind remains unknown.
4524
+ // Todos do not inherit from Object.
4576
4525
  let mut context = graph_test();
4577
4526
  context.index_uri("file:///foo.rb", {
4578
4527
  r"
@@ -4583,6 +4532,7 @@ mod promotability_tests {
4583
4532
 
4584
4533
  context.resolve();
4585
4534
  assert_no_diagnostics!(&context);
4535
+ assert_declaration_kind_eq!(context, "Foo", "<TODO>");
4586
4536
  assert_ancestors_eq!(context, "Foo", ["Foo"]);
4587
4537
  }
4588
4538
 
@@ -4633,8 +4583,8 @@ mod promotability_tests {
4633
4583
  });
4634
4584
 
4635
4585
  context.resolve();
4636
- assert_declaration_kind_eq!(context, "Foo", "Module");
4637
- assert_declaration_kind_eq!(context, "Foo::Bar", "Module");
4586
+ assert_declaration_kind_eq!(context, "Foo", "<TODO>");
4587
+ assert_declaration_kind_eq!(context, "Foo::Bar", "<TODO>");
4638
4588
  assert_declaration_kind_eq!(context, "Foo::Bar::Baz", "Constant");
4639
4589
  }
4640
4590
 
@@ -4652,7 +4602,7 @@ mod promotability_tests {
4652
4602
  });
4653
4603
 
4654
4604
  context.resolve();
4655
- assert_declaration_kind_eq!(context, "Foo", "Module");
4605
+ assert_declaration_kind_eq!(context, "Foo", "<TODO>");
4656
4606
  assert_declaration_exists!(context, "Foo::<Foo>#bar()");
4657
4607
  }
4658
4608
 
@@ -4675,6 +4625,33 @@ mod promotability_tests {
4675
4625
  assert_declaration_does_not_exist!(context, "Foo::<Foo>#bar()");
4676
4626
  }
4677
4627
 
4628
+ #[test]
4629
+ fn rbs_constant_is_promotable_for_singleton_call() {
4630
+ let mut context = graph_test();
4631
+ context.index_rbs_uri("file:///env.rbs", "ENV: untyped");
4632
+ context.index_uri("file:///env.rb", {
4633
+ r#"
4634
+ ENV.fetch("FEATURE")
4635
+ "#
4636
+ });
4637
+ context.resolve();
4638
+
4639
+ assert_no_diagnostics!(&context);
4640
+ assert_declaration_exists!(context, "ENV::<ENV>");
4641
+
4642
+ let fetch = context
4643
+ .graph()
4644
+ .method_references()
4645
+ .values()
4646
+ .find(|method| *method.str() == "fetch".into())
4647
+ .expect("ENV.fetch should be indexed");
4648
+ let receiver_name_id = fetch.receiver().expect("ENV.fetch should have a receiver");
4649
+ let NameRef::Resolved(receiver) = context.graph().names().get(&receiver_name_id).unwrap() else {
4650
+ panic!("ENV.fetch receiver should resolve");
4651
+ };
4652
+ assert_eq!(*receiver.declaration_id(), DeclarationId::from("ENV::<ENV>"));
4653
+ }
4654
+
4678
4655
  #[test]
4679
4656
  fn ivar_defined_inside_of_undefined_alias_namespace() {
4680
4657
  let mut context = graph_test();
@@ -4882,6 +4859,67 @@ mod rbs_tests {
4882
4859
  assert_declaration_exists!(context, "Foo::Bar::Baz");
4883
4860
  }
4884
4861
 
4862
+ #[test]
4863
+ fn rbs_qualified_mixin_resolves_through_parent_scope() {
4864
+ let mut context = graph_test();
4865
+ context.index_rbs_uri("file:///minitest.rbs", {
4866
+ r"
4867
+ module Minitest
4868
+ module Guard
4869
+ end
4870
+
4871
+ module Assertions
4872
+ end
4873
+
4874
+ class Runnable
4875
+ end
4876
+ end
4877
+ "
4878
+ });
4879
+ context.index_rbs_uri("file:///minitest/test.rbs", {
4880
+ r"
4881
+ class Minitest::Test < ::Minitest::Runnable
4882
+ include Minitest::Assertions
4883
+ include Minitest::Guard
4884
+ extend Minitest::Guard
4885
+ end
4886
+ "
4887
+ });
4888
+ context.resolve();
4889
+
4890
+ assert_no_diagnostics!(&context);
4891
+
4892
+ assert_ancestors_eq!(
4893
+ context,
4894
+ "Minitest::Test",
4895
+ [
4896
+ "Minitest::Test",
4897
+ "Minitest::Guard",
4898
+ "Minitest::Assertions",
4899
+ "Minitest::Runnable",
4900
+ "Object",
4901
+ "Kernel",
4902
+ "BasicObject"
4903
+ ]
4904
+ );
4905
+ assert_ancestors_eq!(
4906
+ context,
4907
+ "Minitest::Test::<Test>",
4908
+ [
4909
+ "Minitest::Test::<Test>",
4910
+ "Minitest::Guard",
4911
+ "Minitest::Runnable::<Runnable>",
4912
+ "Object::<Object>",
4913
+ "BasicObject::<BasicObject>",
4914
+ "Class",
4915
+ "Module",
4916
+ "Object",
4917
+ "Kernel",
4918
+ "BasicObject"
4919
+ ]
4920
+ );
4921
+ }
4922
+
4885
4923
  #[test]
4886
4924
  fn rbs_qualified_name_inside_nested_module() {
4887
4925
  let mut context = graph_test();
@@ -5641,4 +5679,164 @@ mod visibility_resolution_tests {
5641
5679
  assert_visibility_eq!(context, "Foo::<Foo>#b()", Visibility::Private);
5642
5680
  assert_visibility_eq!(context, "Foo::<Foo>#c()", Visibility::Public);
5643
5681
  }
5682
+
5683
+ #[test]
5684
+ fn inline_module_function() {
5685
+ let mut context = GraphTest::new();
5686
+ context.index_uri(
5687
+ "file:///foo.rb",
5688
+ r"
5689
+ module Foo
5690
+ module_function def bar; end
5691
+ end
5692
+ ",
5693
+ );
5694
+ context.resolve();
5695
+
5696
+ assert_no_diagnostics!(&context);
5697
+ assert_visibility_eq!(context, "Foo#bar()", Visibility::Private);
5698
+ assert_visibility_eq!(context, "Foo::<Foo>#bar()", Visibility::Public);
5699
+ }
5700
+
5701
+ #[test]
5702
+ fn inline_module_function_singleton_companion_visibility_can_be_changed() {
5703
+ let mut context = graph_test();
5704
+ context.index_uri(
5705
+ "file:///foo.rb",
5706
+ r"
5707
+ module Foo
5708
+ module_function def bar; end
5709
+
5710
+ class << self
5711
+ private :bar
5712
+ end
5713
+ end
5714
+ ",
5715
+ );
5716
+ context.resolve();
5717
+
5718
+ assert_no_diagnostics!(&context);
5719
+ assert_visibility_eq!(context, "Foo#bar()", Visibility::Private);
5720
+ assert_visibility_eq!(context, "Foo::<Foo>#bar()", Visibility::Private);
5721
+ }
5722
+
5723
+ #[test]
5724
+ fn retroactive_module_function() {
5725
+ let mut context = GraphTest::new();
5726
+ context.index_uri(
5727
+ "file:///foo.rb",
5728
+ r"
5729
+ module Foo
5730
+ def bar; end
5731
+ module_function :bar
5732
+ end
5733
+ ",
5734
+ );
5735
+ context.resolve();
5736
+
5737
+ assert_no_diagnostics!(&context);
5738
+ assert_visibility_eq!(context, "Foo#bar()", Visibility::Private);
5739
+ assert_visibility_eq!(context, "Foo::<Foo>#bar()", Visibility::Public);
5740
+
5741
+ // Instance: Method def + MethodVisibility def
5742
+ assert_declaration_definitions_count_eq!(context, "Foo#bar()", 2);
5743
+ // Singleton companion: only the MethodVisibility def is attached
5744
+ assert_declaration_definitions_count_eq!(context, "Foo::<Foo>#bar()", 1);
5745
+ }
5746
+
5747
+ #[test]
5748
+ fn retroactive_module_function_undefined_target_emits_single_diagnostic() {
5749
+ let mut context = GraphTest::new();
5750
+ context.index_uri(
5751
+ "file:///foo.rb",
5752
+ r"
5753
+ module Foo
5754
+ module_function :missing
5755
+ end
5756
+ ",
5757
+ );
5758
+ context.resolve();
5759
+
5760
+ // The singleton-side def stays silent; only the instance-side def emits.
5761
+ assert_diagnostics_eq!(
5762
+ context,
5763
+ &["undefined-method-visibility-target: undefined method `Foo#missing()` for visibility change (2:20-2:27)"]
5764
+ );
5765
+ assert_declaration_does_not_exist!(context, "Foo::<Foo>#missing()");
5766
+ assert_declaration_does_not_exist!(context, "Foo::<Foo>");
5767
+ }
5768
+
5769
+ #[test]
5770
+ fn retroactive_module_function_singleton_companion_cleared_when_removed_multi_file() {
5771
+ let mut context = GraphTest::new();
5772
+ context.index_uri(
5773
+ "file:///a.rb",
5774
+ r"
5775
+ module Foo
5776
+ def bar; end
5777
+ module_function :bar
5778
+ end
5779
+ ",
5780
+ );
5781
+ context.index_uri(
5782
+ "file:///b.rb",
5783
+ r"
5784
+ module Foo
5785
+ def baz; end
5786
+ end
5787
+ ",
5788
+ );
5789
+ context.resolve();
5790
+
5791
+ assert_visibility_eq!(context, "Foo::<Foo>#bar()", Visibility::Public);
5792
+
5793
+ // Re-index a.rb without `module_function :bar`. Foo still has b.rb's Module def, so the
5794
+ // namespace stays alive and no cascade through Foo's singleton class runs. The singleton
5795
+ // companion must still be cleaned up via reverse-lookup invalidation of its own def.
5796
+ context.index_uri(
5797
+ "file:///a.rb",
5798
+ r"
5799
+ module Foo
5800
+ def bar; end
5801
+ end
5802
+ ",
5803
+ );
5804
+ context.resolve();
5805
+
5806
+ assert_no_diagnostics!(&context);
5807
+ assert_visibility_eq!(context, "Foo#bar()", Visibility::Public);
5808
+ assert_declaration_does_not_exist!(context, "Foo::<Foo>#bar()");
5809
+ }
5810
+
5811
+ #[test]
5812
+ fn retroactive_module_function_singleton_companion_cleared_when_removed() {
5813
+ let mut context = GraphTest::new();
5814
+ context.index_uri(
5815
+ "file:///foo.rb",
5816
+ r"
5817
+ module Foo
5818
+ def bar; end
5819
+ module_function :bar
5820
+ end
5821
+ ",
5822
+ );
5823
+ context.resolve();
5824
+
5825
+ assert_visibility_eq!(context, "Foo::<Foo>#bar()", Visibility::Public);
5826
+
5827
+ context.index_uri(
5828
+ "file:///foo.rb",
5829
+ r"
5830
+ module Foo
5831
+ def bar; end
5832
+ end
5833
+ ",
5834
+ );
5835
+ context.resolve();
5836
+
5837
+ assert_no_diagnostics!(&context);
5838
+ assert_visibility_eq!(context, "Foo#bar()", Visibility::Public);
5839
+ assert_declaration_does_not_exist!(context, "Foo::<Foo>#bar()");
5840
+ assert_declaration_does_not_exist!(context, "Foo::<Foo>");
5841
+ }
5644
5842
  }
@@ -291,7 +291,8 @@ pub unsafe extern "C" fn rdx_declaration_singleton_class(pointer: GraphPointer,
291
291
  })
292
292
  }
293
293
 
294
- /// Returns the owner of the declaration (attached object in the case of singleton classes)
294
+ /// Returns the owner of the declaration (attached object in the case of singleton classes), or NULL if the declaration
295
+ /// cannot be found.
295
296
  ///
296
297
  /// # Safety
297
298
  ///
@@ -299,11 +300,13 @@ pub unsafe extern "C" fn rdx_declaration_singleton_class(pointer: GraphPointer,
299
300
  ///
300
301
  /// # Panics
301
302
  ///
302
- /// Will panic if invoked on a non-existing or non-namespace declaration
303
+ /// This function will panic if the owner declaration cannot be found.
303
304
  #[unsafe(no_mangle)]
304
305
  pub unsafe extern "C" fn rdx_declaration_owner(pointer: GraphPointer, decl_id: u64) -> *const CDeclaration {
305
306
  with_graph(pointer, |graph| {
306
- let declaration = graph.declarations().get(&DeclarationId::new(decl_id)).unwrap();
307
+ let Some(declaration) = graph.declarations().get(&DeclarationId::new(decl_id)) else {
308
+ return ptr::null();
309
+ };
307
310
  let owner_id = *declaration.owner_id();
308
311
  Box::into_raw(Box::new(CDeclaration::from_declaration(
309
312
  owner_id,
@@ -156,21 +156,22 @@ pub struct CommentArray {
156
156
  pub len: usize,
157
157
  }
158
158
 
159
- /// Returns a newly allocated array of comments (string and location) for the given definition id.
160
- /// Caller must free the returned pointer with `rdx_definition_comments_free` and each inner string with `free_c_string` if needed.
159
+ /// Returns a newly allocated array of comments (string and location) for the given definition id, or NULL if the
160
+ /// definition cannot be found. Caller must free the returned pointer and its contents with
161
+ /// `rdx_definition_comments_free`.
161
162
  ///
162
163
  /// # Safety
163
164
  /// - `pointer` must be a valid pointer previously returned by `rdx_graph_new`.
164
165
  /// - `definition_id` must be a valid definition id.
165
166
  ///
166
167
  /// # Panics
167
- /// This function will panic if a definition or document cannot be found.
168
+ /// This function will panic if the definition's document cannot be found.
168
169
  #[unsafe(no_mangle)]
169
170
  pub unsafe extern "C" fn rdx_definition_comments(pointer: GraphPointer, definition_id: u64) -> *mut CommentArray {
170
171
  with_graph(pointer, |graph| {
171
172
  let def_id = DefinitionId::new(definition_id);
172
173
  let Some(defn) = graph.definitions().get(&def_id) else {
173
- panic!("Definition not found: {definition_id:?}");
174
+ return ptr::null_mut();
174
175
  };
175
176
 
176
177
  let uri_id = *defn.uri_id();
@@ -229,7 +230,7 @@ pub unsafe extern "C" fn rdx_definition_comments_free(ptr: *mut CommentArray) {
229
230
  // arr is dropped here
230
231
  }
231
232
 
232
- /// Returns a newly allocated `Location` for the given definition id.
233
+ /// Returns a newly allocated `Location` for the given definition id, or NULL if the definition cannot be found.
233
234
  /// Caller must free the returned pointer with `rdx_location_free`.
234
235
  ///
235
236
  /// # Safety
@@ -238,13 +239,13 @@ pub unsafe extern "C" fn rdx_definition_comments_free(ptr: *mut CommentArray) {
238
239
  ///
239
240
  /// # Panics
240
241
  ///
241
- /// This function will panic if a definition or document cannot be found.
242
+ /// This function will panic if the definition's document cannot be found.
242
243
  #[unsafe(no_mangle)]
243
244
  pub unsafe extern "C" fn rdx_definition_location(pointer: GraphPointer, definition_id: u64) -> *mut Location {
244
245
  with_graph(pointer, |graph| {
245
246
  let def_id = DefinitionId::new(definition_id);
246
247
  let Some(defn) = graph.definitions().get(&def_id) else {
247
- panic!("Definition not found: {definition_id:?}");
248
+ return ptr::null_mut();
248
249
  };
249
250
 
250
251
  let document = graph.documents().get(defn.uri_id()).expect("document should exist");
@@ -493,6 +494,25 @@ pub unsafe extern "C" fn rdx_definition_mixins(pointer: GraphPointer, definition
493
494
  })
494
495
  }
495
496
 
497
+ /// Returns a pointer to the URI ID of the document a definition belongs to, or
498
+ /// NULL if the definition cannot be found. Caller must free the returned pointer
499
+ /// with `free_u64`.
500
+ ///
501
+ /// # Safety
502
+ /// - `pointer` must be a valid pointer previously returned by `rdx_graph_new`.
503
+ /// - `definition_id` must be a valid definition id.
504
+ #[unsafe(no_mangle)]
505
+ pub unsafe extern "C" fn rdx_definition_document(pointer: GraphPointer, definition_id: u64) -> *const u64 {
506
+ with_graph(pointer, |graph| {
507
+ let def_id = DefinitionId::new(definition_id);
508
+ if let Some(defn) = graph.definitions().get(&def_id) {
509
+ Box::into_raw(Box::new(**defn.uri_id())).cast_const()
510
+ } else {
511
+ ptr::null()
512
+ }
513
+ })
514
+ }
515
+
496
516
  /// Status of a `MethodAliasDefinition#target` resolution.
497
517
  #[repr(u8)]
498
518
  #[derive(Debug, Clone, Copy, PartialEq, Eq)]