diff options
author | Aleksey Kladov <[email protected]> | 2019-12-08 11:44:14 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-12-08 11:44:14 +0000 |
commit | b37c6a746b6c7cf85dc1ec6e40ac41455b8f2ec0 (patch) | |
tree | c816b6c6fe6e950fc0835259a2a5026e04267d51 | |
parent | b77d7c24aa929e53a2bc2a0ffa319de9bf1ab1fa (diff) |
Remove ty from code_model
-rw-r--r-- | Cargo.lock | 2 | ||||
-rw-r--r-- | crates/ra_cli/Cargo.toml | 4 | ||||
-rw-r--r-- | crates/ra_cli/src/analysis_stats.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 36 | ||||
-rw-r--r-- | crates/ra_hir/src/from_id.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide/src/parent_module.rs | 2 |
9 files changed, 53 insertions, 55 deletions
diff --git a/Cargo.lock b/Cargo.lock index a95f9139f..d80e58548 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -919,6 +919,8 @@ dependencies = [ | |||
919 | "ra_batch 0.1.0", | 919 | "ra_batch 0.1.0", |
920 | "ra_db 0.1.0", | 920 | "ra_db 0.1.0", |
921 | "ra_hir 0.1.0", | 921 | "ra_hir 0.1.0", |
922 | "ra_hir_def 0.1.0", | ||
923 | "ra_hir_ty 0.1.0", | ||
922 | "ra_ide 0.1.0", | 924 | "ra_ide 0.1.0", |
923 | "ra_prof 0.1.0", | 925 | "ra_prof 0.1.0", |
924 | "ra_syntax 0.1.0", | 926 | "ra_syntax 0.1.0", |
diff --git a/crates/ra_cli/Cargo.toml b/crates/ra_cli/Cargo.toml index 21a37c7bf..12af075f7 100644 --- a/crates/ra_cli/Cargo.toml +++ b/crates/ra_cli/Cargo.toml | |||
@@ -12,7 +12,9 @@ env_logger = { version = "0.7.1", default-features = false, features = ["humanti | |||
12 | ra_syntax = { path = "../ra_syntax" } | 12 | ra_syntax = { path = "../ra_syntax" } |
13 | ra_ide = { path = "../ra_ide" } | 13 | ra_ide = { path = "../ra_ide" } |
14 | ra_batch = { path = "../ra_batch" } | 14 | ra_batch = { path = "../ra_batch" } |
15 | ra_hir = { path = "../ra_hir" } | 15 | hir = { path = "../ra_hir", package = "ra_hir" } |
16 | hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } | ||
17 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } | ||
16 | ra_db = { path = "../ra_db" } | 18 | ra_db = { path = "../ra_db" } |
17 | 19 | ||
18 | [dependencies.ra_prof] | 20 | [dependencies.ra_prof] |
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index 9b1802a5f..ac65415a5 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs | |||
@@ -2,8 +2,13 @@ | |||
2 | 2 | ||
3 | use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; | 3 | use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; |
4 | 4 | ||
5 | use hir::{ | ||
6 | db::{DefDatabase, HirDatabase}, | ||
7 | AssocItem, Crate, HasSource, HirDisplay, ModuleDef, | ||
8 | }; | ||
9 | use hir_def::FunctionId; | ||
10 | use hir_ty::{Ty, TypeWalk}; | ||
5 | use ra_db::SourceDatabaseExt; | 11 | use ra_db::SourceDatabaseExt; |
6 | use ra_hir::{AssocItem, Crate, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk}; | ||
7 | use ra_syntax::AstNode; | 12 | use ra_syntax::AstNode; |
8 | 13 | ||
9 | use crate::{progress_report::ProgressReport, Result, Verbosity}; | 14 | use crate::{progress_report::ProgressReport, Result, Verbosity}; |
@@ -101,8 +106,9 @@ pub fn run( | |||
101 | continue; | 106 | continue; |
102 | } | 107 | } |
103 | } | 108 | } |
104 | let body = f.body(db); | 109 | let f_id = FunctionId::from(f); |
105 | let inference_result = f.infer(db); | 110 | let body = db.body(f_id.into()); |
111 | let inference_result = db.infer(f_id.into()); | ||
106 | for (expr_id, _) in body.exprs.iter() { | 112 | for (expr_id, _) in body.exprs.iter() { |
107 | let ty = &inference_result[expr_id]; | 113 | let ty = &inference_result[expr_id]; |
108 | num_exprs += 1; | 114 | num_exprs += 1; |
@@ -122,7 +128,8 @@ pub fn run( | |||
122 | if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) { | 128 | if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) { |
123 | num_type_mismatches += 1; | 129 | num_type_mismatches += 1; |
124 | if verbosity.is_verbose() { | 130 | if verbosity.is_verbose() { |
125 | let src = f.body_source_map(db).expr_syntax(expr_id); | 131 | let (_, sm) = db.body_with_source_map(f_id.into()); |
132 | let src = sm.expr_syntax(expr_id); | ||
126 | if let Some(src) = src { | 133 | if let Some(src) = src { |
127 | // FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly | 134 | // FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly |
128 | let original_file = src.file_id.original_file(db); | 135 | let original_file = src.file_id.original_file(db); |
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 906716dfc..3d956afa7 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -23,14 +23,15 @@ use hir_expand::{ | |||
23 | name::{self, AsName}, | 23 | name::{self, AsName}, |
24 | MacroDefId, | 24 | MacroDefId, |
25 | }; | 25 | }; |
26 | use hir_ty::expr::ExprValidator; | 26 | use hir_ty::{ |
27 | autoderef, display::HirFormatter, expr::ExprValidator, ApplicationTy, Canonical, InEnvironment, | ||
28 | TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, | ||
29 | }; | ||
27 | use ra_db::{CrateId, Edition, FileId}; | 30 | use ra_db::{CrateId, Edition, FileId}; |
28 | use ra_syntax::ast; | 31 | use ra_syntax::ast; |
29 | 32 | ||
30 | use crate::{ | 33 | use crate::{ |
31 | db::{DefDatabase, HirDatabase}, | 34 | db::{DefDatabase, HirDatabase}, |
32 | ty::display::HirFormatter, | ||
33 | ty::{self, InEnvironment, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk}, | ||
34 | CallableDef, HirDisplay, InFile, Name, | 35 | CallableDef, HirDisplay, InFile, Name, |
35 | }; | 36 | }; |
36 | 37 | ||
@@ -87,10 +88,6 @@ impl Crate { | |||
87 | pub fn all(db: &impl DefDatabase) -> Vec<Crate> { | 88 | pub fn all(db: &impl DefDatabase) -> Vec<Crate> { |
88 | db.crate_graph().iter().map(|id| Crate { id }).collect() | 89 | db.crate_graph().iter().map(|id| Crate { id }).collect() |
89 | } | 90 | } |
90 | |||
91 | pub fn crate_id(self) -> CrateId { | ||
92 | self.id | ||
93 | } | ||
94 | } | 91 | } |
95 | 92 | ||
96 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 93 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -937,7 +934,7 @@ impl Type { | |||
937 | pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { | 934 | pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { |
938 | if let Ty::Apply(a_ty) = &self.ty.value { | 935 | if let Ty::Apply(a_ty) = &self.ty.value { |
939 | match a_ty.ctor { | 936 | match a_ty.ctor { |
940 | ty::TypeCtor::Adt(AdtId::StructId(s)) => { | 937 | TypeCtor::Adt(AdtId::StructId(s)) => { |
941 | let var_def = s.into(); | 938 | let var_def = s.into(); |
942 | return db | 939 | return db |
943 | .field_types(var_def) | 940 | .field_types(var_def) |
@@ -959,7 +956,7 @@ impl Type { | |||
959 | let mut res = Vec::new(); | 956 | let mut res = Vec::new(); |
960 | if let Ty::Apply(a_ty) = &self.ty.value { | 957 | if let Ty::Apply(a_ty) = &self.ty.value { |
961 | match a_ty.ctor { | 958 | match a_ty.ctor { |
962 | ty::TypeCtor::Tuple { .. } => { | 959 | TypeCtor::Tuple { .. } => { |
963 | for ty in a_ty.parameters.iter() { | 960 | for ty in a_ty.parameters.iter() { |
964 | let ty = ty.clone().subst(&a_ty.parameters); | 961 | let ty = ty.clone().subst(&a_ty.parameters); |
965 | res.push(self.derived(ty)); | 962 | res.push(self.derived(ty)); |
@@ -995,10 +992,10 @@ impl Type { | |||
995 | pub fn autoderef<'a>(&'a self, db: &'a impl HirDatabase) -> impl Iterator<Item = Type> + 'a { | 992 | pub fn autoderef<'a>(&'a self, db: &'a impl HirDatabase) -> impl Iterator<Item = Type> + 'a { |
996 | // There should be no inference vars in types passed here | 993 | // There should be no inference vars in types passed here |
997 | // FIXME check that? | 994 | // FIXME check that? |
998 | let canonical = crate::ty::Canonical { value: self.ty.value.clone(), num_vars: 0 }; | 995 | let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 }; |
999 | let environment = self.ty.environment.clone(); | 996 | let environment = self.ty.environment.clone(); |
1000 | let ty = InEnvironment { value: canonical, environment: environment.clone() }; | 997 | let ty = InEnvironment { value: canonical, environment: environment.clone() }; |
1001 | ty::autoderef(db, Some(self.krate), ty) | 998 | autoderef(db, Some(self.krate), ty) |
1002 | .map(|canonical| canonical.value) | 999 | .map(|canonical| canonical.value) |
1003 | .map(move |ty| self.derived(ty)) | 1000 | .map(move |ty| self.derived(ty)) |
1004 | } | 1001 | } |
@@ -1038,15 +1035,14 @@ impl Type { | |||
1038 | // FIXME: provide required accessors such that it becomes implementable from outside. | 1035 | // FIXME: provide required accessors such that it becomes implementable from outside. |
1039 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { | 1036 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { |
1040 | match (&self.ty.value, &other.ty.value) { | 1037 | match (&self.ty.value, &other.ty.value) { |
1041 | (Ty::Apply(a_original_ty), Ty::Apply(ty::ApplicationTy { ctor, parameters })) => { | 1038 | (Ty::Apply(a_original_ty), Ty::Apply(ApplicationTy { ctor, parameters })) => match ctor |
1042 | match ctor { | 1039 | { |
1043 | TypeCtor::Ref(..) => match parameters.as_single() { | 1040 | TypeCtor::Ref(..) => match parameters.as_single() { |
1044 | Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor, | 1041 | Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor, |
1045 | _ => false, | 1042 | _ => false, |
1046 | }, | 1043 | }, |
1047 | _ => a_original_ty.ctor == *ctor, | 1044 | _ => a_original_ty.ctor == *ctor, |
1048 | } | 1045 | }, |
1049 | } | ||
1050 | _ => false, | 1046 | _ => false, |
1051 | } | 1047 | } |
1052 | } | 1048 | } |
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index 0398d0ee6..75a1a7772 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs | |||
@@ -9,16 +9,10 @@ use hir_def::{ | |||
9 | }; | 9 | }; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | Adt, AssocItem, AttrDef, Crate, DefWithBody, EnumVariant, GenericDef, ModuleDef, StructField, | 12 | Adt, AssocItem, AttrDef, DefWithBody, EnumVariant, GenericDef, ModuleDef, StructField, |
13 | VariantDef, | 13 | VariantDef, |
14 | }; | 14 | }; |
15 | 15 | ||
16 | impl From<ra_db::CrateId> for Crate { | ||
17 | fn from(id: ra_db::CrateId) -> Self { | ||
18 | Crate { id } | ||
19 | } | ||
20 | } | ||
21 | |||
22 | macro_rules! from_id { | 16 | macro_rules! from_id { |
23 | ($(($id:path, $ty:path)),*) => {$( | 17 | ($(($id:path, $ty:path)),*) => {$( |
24 | impl From<$id> for $ty { | 18 | impl From<$id> for $ty { |
@@ -26,10 +20,16 @@ macro_rules! from_id { | |||
26 | $ty { id } | 20 | $ty { id } |
27 | } | 21 | } |
28 | } | 22 | } |
23 | impl From<$ty> for $id { | ||
24 | fn from(ty: $ty) -> $id { | ||
25 | ty.id | ||
26 | } | ||
27 | } | ||
29 | )*} | 28 | )*} |
30 | } | 29 | } |
31 | 30 | ||
32 | from_id![ | 31 | from_id![ |
32 | (ra_db::CrateId, crate::Crate), | ||
33 | (hir_def::ModuleId, crate::Module), | 33 | (hir_def::ModuleId, crate::Module), |
34 | (hir_def::StructId, crate::Struct), | 34 | (hir_def::StructId, crate::Struct), |
35 | (hir_def::UnionId, crate::Union), | 35 | (hir_def::UnionId, crate::Union), |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 9eb34b5dc..bb22882b1 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -31,7 +31,6 @@ pub mod debug; | |||
31 | pub mod db; | 31 | pub mod db; |
32 | pub mod source_binder; | 32 | pub mod source_binder; |
33 | 33 | ||
34 | mod ty; | ||
35 | pub mod diagnostics; | 34 | pub mod diagnostics; |
36 | 35 | ||
37 | mod from_id; | 36 | mod from_id; |
@@ -48,11 +47,6 @@ pub use crate::{ | |||
48 | }, | 47 | }, |
49 | from_source::FromSource, | 48 | from_source::FromSource, |
50 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, | 49 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, |
51 | ty::{ | ||
52 | display::HirDisplay, | ||
53 | primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}, | ||
54 | ApplicationTy, CallableDef, Substs, TraitRef, Ty, TypeCtor, TypeWalk, | ||
55 | }, | ||
56 | }; | 50 | }; |
57 | 51 | ||
58 | pub use hir_def::{ | 52 | pub use hir_def::{ |
@@ -66,3 +60,4 @@ pub use hir_def::{ | |||
66 | pub use hir_expand::{ | 60 | pub use hir_expand::{ |
67 | name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, | 61 | name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, |
68 | }; | 62 | }; |
63 | pub use hir_ty::{display::HirDisplay, CallableDef}; | ||
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index c5a920688..9efd0477c 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -22,6 +22,10 @@ use hir_def::{ | |||
22 | use hir_expand::{ | 22 | use hir_expand::{ |
23 | hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind, | 23 | hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind, |
24 | }; | 24 | }; |
25 | use hir_ty::{ | ||
26 | method_resolution::{self, implements_trait}, | ||
27 | Canonical, InEnvironment, InferenceResult, TraitEnvironment, Ty, | ||
28 | }; | ||
25 | use ra_syntax::{ | 29 | use ra_syntax::{ |
26 | ast::{self, AstNode}, | 30 | ast::{self, AstNode}, |
27 | match_ast, AstPtr, | 31 | match_ast, AstPtr, |
@@ -30,13 +34,9 @@ use ra_syntax::{ | |||
30 | }; | 34 | }; |
31 | 35 | ||
32 | use crate::{ | 36 | use crate::{ |
33 | db::HirDatabase, | 37 | db::HirDatabase, Adt, AssocItem, Const, DefWithBody, Enum, EnumVariant, FromSource, Function, |
34 | ty::{ | 38 | ImplBlock, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, |
35 | method_resolution::{self, implements_trait}, | 39 | TypeParam, |
36 | InEnvironment, TraitEnvironment, Ty, | ||
37 | }, | ||
38 | Adt, AssocItem, Const, DefWithBody, Enum, EnumVariant, FromSource, Function, ImplBlock, Local, | ||
39 | MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, | ||
40 | }; | 40 | }; |
41 | 41 | ||
42 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> Option<Resolver> { | 42 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> Option<Resolver> { |
@@ -100,7 +100,7 @@ pub struct SourceAnalyzer { | |||
100 | resolver: Resolver, | 100 | resolver: Resolver, |
101 | body_owner: Option<DefWithBody>, | 101 | body_owner: Option<DefWithBody>, |
102 | body_source_map: Option<Arc<BodySourceMap>>, | 102 | body_source_map: Option<Arc<BodySourceMap>>, |
103 | infer: Option<Arc<crate::ty::InferenceResult>>, | 103 | infer: Option<Arc<InferenceResult>>, |
104 | scopes: Option<Arc<ExprScopes>>, | 104 | scopes: Option<Arc<ExprScopes>>, |
105 | } | 105 | } |
106 | 106 | ||
@@ -376,7 +376,7 @@ impl SourceAnalyzer { | |||
376 | // There should be no inference vars in types passed here | 376 | // There should be no inference vars in types passed here |
377 | // FIXME check that? | 377 | // FIXME check that? |
378 | // FIXME replace Unknown by bound vars here | 378 | // FIXME replace Unknown by bound vars here |
379 | let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; | 379 | let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 }; |
380 | method_resolution::iterate_method_candidates( | 380 | method_resolution::iterate_method_candidates( |
381 | &canonical, | 381 | &canonical, |
382 | db, | 382 | db, |
@@ -400,7 +400,7 @@ impl SourceAnalyzer { | |||
400 | // There should be no inference vars in types passed here | 400 | // There should be no inference vars in types passed here |
401 | // FIXME check that? | 401 | // FIXME check that? |
402 | // FIXME replace Unknown by bound vars here | 402 | // FIXME replace Unknown by bound vars here |
403 | let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; | 403 | let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 }; |
404 | method_resolution::iterate_method_candidates( | 404 | method_resolution::iterate_method_candidates( |
405 | &canonical, | 405 | &canonical, |
406 | db, | 406 | db, |
@@ -418,7 +418,7 @@ impl SourceAnalyzer { | |||
418 | // ) -> impl Iterator<Item = Ty> + 'a { | 418 | // ) -> impl Iterator<Item = Ty> + 'a { |
419 | // // There should be no inference vars in types passed here | 419 | // // There should be no inference vars in types passed here |
420 | // // FIXME check that? | 420 | // // FIXME check that? |
421 | // let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; | 421 | // let canonical = Canonical { value: ty, num_vars: 0 }; |
422 | // let krate = self.resolver.krate(); | 422 | // let krate = self.resolver.krate(); |
423 | // let environment = TraitEnvironment::lower(db, &self.resolver); | 423 | // let environment = TraitEnvironment::lower(db, &self.resolver); |
424 | // let ty = crate::ty::InEnvironment { value: canonical, environment }; | 424 | // let ty = crate::ty::InEnvironment { value: canonical, environment }; |
@@ -440,7 +440,7 @@ impl SourceAnalyzer { | |||
440 | _ => return false, | 440 | _ => return false, |
441 | }; | 441 | }; |
442 | 442 | ||
443 | let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 }; | 443 | let canonical_ty = Canonical { value: ty, num_vars: 0 }; |
444 | implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait) | 444 | implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait) |
445 | } | 445 | } |
446 | 446 | ||
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs deleted file mode 100644 index 4ed69c00d..000000000 --- a/crates/ra_hir/src/ty.rs +++ /dev/null | |||
@@ -1,4 +0,0 @@ | |||
1 | //! The type system. We currently use this to infer types for completion, hover | ||
2 | //! information and various assists. | ||
3 | |||
4 | pub use hir_ty::*; | ||
diff --git a/crates/ra_ide/src/parent_module.rs b/crates/ra_ide/src/parent_module.rs index aef3fa3df..f5a788c07 100644 --- a/crates/ra_ide/src/parent_module.rs +++ b/crates/ra_ide/src/parent_module.rs | |||
@@ -30,7 +30,7 @@ pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> { | |||
30 | None => return Vec::new(), | 30 | None => return Vec::new(), |
31 | }; | 31 | }; |
32 | let krate = module.krate(); | 32 | let krate = module.krate(); |
33 | vec![krate.crate_id()] | 33 | vec![krate.into()] |
34 | } | 34 | } |
35 | 35 | ||
36 | #[cfg(test)] | 36 | #[cfg(test)] |