aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/assists/src/handlers/qualify_path.rs182
-rw-r--r--crates/assists/src/utils/import_assets.rs6
-rw-r--r--crates/assists/src/utils/insert_use.rs4
-rw-r--r--crates/base_db/src/input.rs4
-rw-r--r--crates/base_db/src/lib.rs4
-rw-r--r--crates/completion/src/completions/postfix/format_like.rs6
-rw-r--r--crates/hir/src/code_model.rs14
-rw-r--r--crates/hir/src/from_id.rs8
-rw-r--r--crates/hir/src/has_source.rs3
-rw-r--r--crates/hir/src/lib.rs3
-rw-r--r--crates/hir_def/src/body/diagnostics.rs4
-rw-r--r--crates/hir_def/src/body/lower.rs6
-rw-r--r--crates/hir_def/src/lib.rs6
-rw-r--r--crates/hir_def/src/nameres/collector.rs14
-rw-r--r--crates/hir_def/src/test_db.rs14
-rw-r--r--crates/hir_expand/src/test_db.rs2
-rw-r--r--crates/hir_ty/Cargo.toml6
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check/case_conv.rs6
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs15
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs8
-rw-r--r--crates/hir_ty/src/display.rs149
-rw-r--r--crates/hir_ty/src/infer.rs8
-rw-r--r--crates/hir_ty/src/infer/expr.rs2
-rw-r--r--crates/hir_ty/src/infer/unify.rs37
-rw-r--r--crates/hir_ty/src/lib.rs3
-rw-r--r--crates/hir_ty/src/test_db.rs6
-rw-r--r--crates/hir_ty/src/tests.rs8
-rw-r--r--crates/hir_ty/src/traits/chalk.rs23
-rw-r--r--crates/hir_ty/src/traits/chalk/interner.rs37
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs362
-rw-r--r--crates/hir_ty/src/traits/chalk/tls.rs162
-rw-r--r--crates/ide/src/diagnostics/fixes.rs2
-rw-r--r--crates/ide/src/doc_links.rs9
-rw-r--r--crates/ide/src/file_structure.rs2
-rw-r--r--crates/ide/src/inlay_hints.rs21
-rw-r--r--crates/ide/src/join_lines.rs2
-rw-r--r--crates/ide/src/lib.rs14
-rw-r--r--crates/ide/src/markdown_remove.rs3
-rw-r--r--crates/ide/src/matching_brace.rs2
-rw-r--r--crates/ide/src/references.rs8
-rw-r--r--crates/ide/src/runnables.rs70
-rw-r--r--crates/ide/src/syntax_highlighting.rs9
-rw-r--r--crates/mbe/src/mbe_expander/matcher.rs10
-rw-r--r--crates/mbe/src/subtree_source.rs10
-rw-r--r--crates/proc_macro_api/src/process.rs8
-rw-r--r--crates/proc_macro_api/src/rpc.rs34
-rw-r--r--crates/proc_macro_srv/src/lib.rs1
-rw-r--r--crates/profile/src/hprof.rs4
-rw-r--r--crates/profile/src/tree.rs16
-rw-r--r--crates/project_model/src/cargo_workspace.rs4
-rw-r--r--crates/project_model/src/sysroot.rs9
-rw-r--r--crates/rust-analyzer/src/bin/main.rs2
-rw-r--r--crates/rust-analyzer/src/cli/progress_report.rs16
-rw-r--r--crates/rust-analyzer/src/dispatch.rs40
-rw-r--r--crates/rust-analyzer/src/document.rs4
-rw-r--r--crates/rust-analyzer/src/global_state.rs2
-rw-r--r--crates/rust-analyzer/src/lib.rs10
-rw-r--r--crates/rust-analyzer/src/main_loop.rs111
-rw-r--r--crates/rust-analyzer/src/semantic_tokens.rs10
-rw-r--r--crates/rust-analyzer/tests/rust-analyzer/support.rs28
-rw-r--r--crates/rust-analyzer/tests/rust-analyzer/testdir.rs8
-rw-r--r--crates/ssr/src/parsing.rs2
-rw-r--r--crates/syntax/Cargo.toml4
-rw-r--r--crates/syntax/src/ast.rs2
-rw-r--r--crates/syntax/src/ast/generated.rs6
-rw-r--r--crates/syntax/src/lib.rs11
-rw-r--r--crates/syntax/src/parsing.rs4
-rw-r--r--crates/syntax/src/parsing/text_token_source.rs2
-rw-r--r--crates/syntax/src/syntax_node.rs6
-rw-r--r--crates/vfs/src/vfs_path.rs6
70 files changed, 901 insertions, 723 deletions
diff --git a/crates/assists/src/handlers/qualify_path.rs b/crates/assists/src/handlers/qualify_path.rs
index f436bdbbf..d5bc4e574 100644
--- a/crates/assists/src/handlers/qualify_path.rs
+++ b/crates/assists/src/handlers/qualify_path.rs
@@ -56,12 +56,14 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
56 ImportCandidate::QualifierStart(_) => { 56 ImportCandidate::QualifierStart(_) => {
57 mark::hit!(qualify_path_qualifier_start); 57 mark::hit!(qualify_path_qualifier_start);
58 let path = ast::Path::cast(import_assets.syntax_under_caret().clone())?; 58 let path = ast::Path::cast(import_assets.syntax_under_caret().clone())?;
59 let segment = path.segment()?; 59 let (prev_segment, segment) = (path.qualifier()?.segment()?, path.segment()?);
60 QualifyCandidate::QualifierStart(segment) 60 QualifyCandidate::QualifierStart(segment, prev_segment.generic_arg_list())
61 } 61 }
62 ImportCandidate::UnqualifiedName(_) => { 62 ImportCandidate::UnqualifiedName(_) => {
63 mark::hit!(qualify_path_unqualified_name); 63 mark::hit!(qualify_path_unqualified_name);
64 QualifyCandidate::UnqualifiedName 64 let path = ast::Path::cast(import_assets.syntax_under_caret().clone())?;
65 let generics = path.segment()?.generic_arg_list();
66 QualifyCandidate::UnqualifiedName(generics)
65 } 67 }
66 ImportCandidate::TraitAssocItem(_) => { 68 ImportCandidate::TraitAssocItem(_) => {
67 mark::hit!(qualify_path_trait_assoc_item); 69 mark::hit!(qualify_path_trait_assoc_item);
@@ -96,22 +98,25 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
96} 98}
97 99
98enum QualifyCandidate<'db> { 100enum QualifyCandidate<'db> {
99 QualifierStart(ast::PathSegment), 101 QualifierStart(ast::PathSegment, Option<ast::GenericArgList>),
100 UnqualifiedName, 102 UnqualifiedName(Option<ast::GenericArgList>),
101 TraitAssocItem(ast::Path, ast::PathSegment), 103 TraitAssocItem(ast::Path, ast::PathSegment),
102 TraitMethod(&'db RootDatabase, ast::MethodCallExpr), 104 TraitMethod(&'db RootDatabase, ast::MethodCallExpr),
103} 105}
104 106
105impl QualifyCandidate<'_> { 107impl QualifyCandidate<'_> {
106 fn qualify(&self, mut replacer: impl FnMut(String), import: hir::ModPath, item: hir::ItemInNs) { 108 fn qualify(&self, mut replacer: impl FnMut(String), import: hir::ModPath, item: hir::ItemInNs) {
109 let import = mod_path_to_ast(&import);
107 match self { 110 match self {
108 QualifyCandidate::QualifierStart(segment) => { 111 QualifyCandidate::QualifierStart(segment, generics) => {
109 let import = mod_path_to_ast(&import); 112 let generics = generics.as_ref().map_or_else(String::new, ToString::to_string);
110 replacer(format!("{}::{}", import, segment)); 113 replacer(format!("{}{}::{}", import, generics, segment));
114 }
115 QualifyCandidate::UnqualifiedName(generics) => {
116 let generics = generics.as_ref().map_or_else(String::new, ToString::to_string);
117 replacer(format!("{}{}", import.to_string(), generics));
111 } 118 }
112 QualifyCandidate::UnqualifiedName => replacer(mod_path_to_ast(&import).to_string()),
113 QualifyCandidate::TraitAssocItem(qualifier, segment) => { 119 QualifyCandidate::TraitAssocItem(qualifier, segment) => {
114 let import = mod_path_to_ast(&import);
115 replacer(format!("<{} as {}>::{}", qualifier, import, segment)); 120 replacer(format!("<{} as {}>::{}", qualifier, import, segment));
116 } 121 }
117 &QualifyCandidate::TraitMethod(db, ref mcall_expr) => { 122 &QualifyCandidate::TraitMethod(db, ref mcall_expr) => {
@@ -124,25 +129,27 @@ impl QualifyCandidate<'_> {
124 db: &RootDatabase, 129 db: &RootDatabase,
125 mcall_expr: &ast::MethodCallExpr, 130 mcall_expr: &ast::MethodCallExpr,
126 mut replacer: impl FnMut(String), 131 mut replacer: impl FnMut(String),
127 import: hir::ModPath, 132 import: ast::Path,
128 item: hir::ItemInNs, 133 item: hir::ItemInNs,
129 ) -> Option<()> { 134 ) -> Option<()> {
130 let receiver = mcall_expr.receiver()?; 135 let receiver = mcall_expr.receiver()?;
131 let trait_method_name = mcall_expr.name_ref()?; 136 let trait_method_name = mcall_expr.name_ref()?;
137 let generics =
138 mcall_expr.generic_arg_list().as_ref().map_or_else(String::new, ToString::to_string);
132 let arg_list = mcall_expr.arg_list().map(|arg_list| arg_list.args()); 139 let arg_list = mcall_expr.arg_list().map(|arg_list| arg_list.args());
133 let trait_ = item_as_trait(item)?; 140 let trait_ = item_as_trait(item)?;
134 let method = find_trait_method(db, trait_, &trait_method_name)?; 141 let method = find_trait_method(db, trait_, &trait_method_name)?;
135 if let Some(self_access) = method.self_param(db).map(|sp| sp.access(db)) { 142 if let Some(self_access) = method.self_param(db).map(|sp| sp.access(db)) {
136 let import = mod_path_to_ast(&import);
137 let receiver = match self_access { 143 let receiver = match self_access {
138 hir::Access::Shared => make::expr_ref(receiver, false), 144 hir::Access::Shared => make::expr_ref(receiver, false),
139 hir::Access::Exclusive => make::expr_ref(receiver, true), 145 hir::Access::Exclusive => make::expr_ref(receiver, true),
140 hir::Access::Owned => receiver, 146 hir::Access::Owned => receiver,
141 }; 147 };
142 replacer(format!( 148 replacer(format!(
143 "{}::{}{}", 149 "{}::{}{}{}",
144 import, 150 import,
145 trait_method_name, 151 trait_method_name,
152 generics,
146 match arg_list.clone() { 153 match arg_list.clone() {
147 Some(args) => make::arg_list(iter::once(receiver).chain(args)), 154 Some(args) => make::arg_list(iter::once(receiver).chain(args)),
148 None => make::arg_list(iter::once(receiver)), 155 None => make::arg_list(iter::once(receiver)),
@@ -1045,4 +1052,153 @@ fn main() {
1045", 1052",
1046 ); 1053 );
1047 } 1054 }
1055
1056 #[test]
1057 fn keep_generic_annotations() {
1058 check_assist(
1059 qualify_path,
1060 r"
1061//- /lib.rs crate:dep
1062pub mod generic { pub struct Thing<'a, T>(&'a T); }
1063
1064//- /main.rs crate:main deps:dep
1065fn foo() -> Thin<|>g<'static, ()> {}
1066
1067fn main() {}
1068",
1069 r"
1070fn foo() -> dep::generic::Thing<'static, ()> {}
1071
1072fn main() {}
1073",
1074 );
1075 }
1076
1077 #[test]
1078 fn keep_generic_annotations_leading_colon() {
1079 check_assist(
1080 qualify_path,
1081 r"
1082//- /lib.rs crate:dep
1083pub mod generic { pub struct Thing<'a, T>(&'a T); }
1084
1085//- /main.rs crate:main deps:dep
1086fn foo() -> Thin<|>g::<'static, ()> {}
1087
1088fn main() {}
1089",
1090 r"
1091fn foo() -> dep::generic::Thing::<'static, ()> {}
1092
1093fn main() {}
1094",
1095 );
1096 }
1097
1098 #[test]
1099 fn associated_struct_const_generic() {
1100 check_assist(
1101 qualify_path,
1102 r"
1103 mod test_mod {
1104 pub struct TestStruct<T> {}
1105 impl<T> TestStruct<T> {
1106 const TEST_CONST: u8 = 42;
1107 }
1108 }
1109
1110 fn main() {
1111 TestStruct::<()>::TEST_CONST<|>
1112 }
1113 ",
1114 r"
1115 mod test_mod {
1116 pub struct TestStruct<T> {}
1117 impl<T> TestStruct<T> {
1118 const TEST_CONST: u8 = 42;
1119 }
1120 }
1121
1122 fn main() {
1123 test_mod::TestStruct::<()>::TEST_CONST
1124 }
1125 ",
1126 );
1127 }
1128
1129 #[test]
1130 fn associated_trait_const_generic() {
1131 check_assist(
1132 qualify_path,
1133 r"
1134 mod test_mod {
1135 pub trait TestTrait {
1136 const TEST_CONST: u8;
1137 }
1138 pub struct TestStruct<T> {}
1139 impl<T> TestTrait for TestStruct<T> {
1140 const TEST_CONST: u8 = 42;
1141 }
1142 }
1143
1144 fn main() {
1145 test_mod::TestStruct::<()>::TEST_CONST<|>
1146 }
1147 ",
1148 r"
1149 mod test_mod {
1150 pub trait TestTrait {
1151 const TEST_CONST: u8;
1152 }
1153 pub struct TestStruct<T> {}
1154 impl<T> TestTrait for TestStruct<T> {
1155 const TEST_CONST: u8 = 42;
1156 }
1157 }
1158
1159 fn main() {
1160 <test_mod::TestStruct::<()> as test_mod::TestTrait>::TEST_CONST
1161 }
1162 ",
1163 );
1164 }
1165
1166 #[test]
1167 fn trait_method_generic() {
1168 check_assist(
1169 qualify_path,
1170 r"
1171 mod test_mod {
1172 pub trait TestTrait {
1173 fn test_method<T>(&self);
1174 }
1175 pub struct TestStruct {}
1176 impl TestTrait for TestStruct {
1177 fn test_method<T>(&self) {}
1178 }
1179 }
1180
1181 fn main() {
1182 let test_struct = test_mod::TestStruct {};
1183 test_struct.test_meth<|>od::<()>()
1184 }
1185 ",
1186 r"
1187 mod test_mod {
1188 pub trait TestTrait {
1189 fn test_method<T>(&self);
1190 }
1191 pub struct TestStruct {}
1192 impl TestTrait for TestStruct {
1193 fn test_method<T>(&self) {}
1194 }
1195 }
1196
1197 fn main() {
1198 let test_struct = test_mod::TestStruct {};
1199 test_mod::TestTrait::test_method::<()>(&test_struct)
1200 }
1201 ",
1202 );
1203 }
1048} 1204}
diff --git a/crates/assists/src/utils/import_assets.rs b/crates/assists/src/utils/import_assets.rs
index 23db3a74b..f47edbb76 100644
--- a/crates/assists/src/utils/import_assets.rs
+++ b/crates/assists/src/utils/import_assets.rs
@@ -26,13 +26,13 @@ pub(crate) enum ImportCandidate {
26 26
27#[derive(Debug)] 27#[derive(Debug)]
28pub(crate) struct TraitImportCandidate { 28pub(crate) struct TraitImportCandidate {
29 pub ty: hir::Type, 29 pub(crate) ty: hir::Type,
30 pub name: ast::NameRef, 30 pub(crate) name: ast::NameRef,
31} 31}
32 32
33#[derive(Debug)] 33#[derive(Debug)]
34pub(crate) struct PathImportCandidate { 34pub(crate) struct PathImportCandidate {
35 pub name: ast::NameRef, 35 pub(crate) name: ast::NameRef,
36} 36}
37 37
38#[derive(Debug)] 38#[derive(Debug)]
diff --git a/crates/assists/src/utils/insert_use.rs b/crates/assists/src/utils/insert_use.rs
index 033fbcedc..a76bd5ebf 100644
--- a/crates/assists/src/utils/insert_use.rs
+++ b/crates/assists/src/utils/insert_use.rs
@@ -17,13 +17,13 @@ use syntax::{
17use test_utils::mark; 17use test_utils::mark;
18 18
19#[derive(Debug)] 19#[derive(Debug)]
20pub enum ImportScope { 20pub(crate) enum ImportScope {
21 File(ast::SourceFile), 21 File(ast::SourceFile),
22 Module(ast::ItemList), 22 Module(ast::ItemList),
23} 23}
24 24
25impl ImportScope { 25impl ImportScope {
26 pub fn from(syntax: SyntaxNode) -> Option<Self> { 26 pub(crate) fn from(syntax: SyntaxNode) -> Option<Self> {
27 if let Some(module) = ast::Module::cast(syntax.clone()) { 27 if let Some(module) = ast::Module::cast(syntax.clone()) {
28 module.item_list().map(ImportScope::Module) 28 module.item_list().map(ImportScope::Module)
29 } else if let this @ Some(_) = ast::SourceFile::cast(syntax.clone()) { 29 } else if let this @ Some(_) = ast::SourceFile::cast(syntax.clone()) {
diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs
index 87f0a0ce5..31907ed98 100644
--- a/crates/base_db/src/input.rs
+++ b/crates/base_db/src/input.rs
@@ -12,9 +12,7 @@ use cfg::CfgOptions;
12use rustc_hash::{FxHashMap, FxHashSet}; 12use rustc_hash::{FxHashMap, FxHashSet};
13use syntax::SmolStr; 13use syntax::SmolStr;
14use tt::TokenExpander; 14use tt::TokenExpander;
15use vfs::{file_set::FileSet, VfsPath}; 15use vfs::{file_set::FileSet, FileId, VfsPath};
16
17pub use vfs::FileId;
18 16
19/// Files are grouped into source roots. A source root is a directory on the 17/// Files are grouped into source roots. A source root is a directory on the
20/// file systems which is watched for changes. Typically it corresponds to a 18/// file systems which is watched for changes. Typically it corresponds to a
diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs
index 0804202d6..ce75a5337 100644
--- a/crates/base_db/src/lib.rs
+++ b/crates/base_db/src/lib.rs
@@ -14,11 +14,11 @@ pub use crate::{
14 change::Change, 14 change::Change,
15 input::{ 15 input::{
16 CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, Dependency, Edition, Env, 16 CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, Dependency, Edition, Env,
17 FileId, ProcMacroId, SourceRoot, SourceRootId, 17 ProcMacroId, SourceRoot, SourceRootId,
18 }, 18 },
19}; 19};
20pub use salsa; 20pub use salsa;
21pub use vfs::{file_set::FileSet, VfsPath}; 21pub use vfs::{file_set::FileSet, FileId, VfsPath};
22 22
23#[macro_export] 23#[macro_export]
24macro_rules! impl_intern_key { 24macro_rules! impl_intern_key {
diff --git a/crates/completion/src/completions/postfix/format_like.rs b/crates/completion/src/completions/postfix/format_like.rs
index f35114ed1..88ba86acb 100644
--- a/crates/completion/src/completions/postfix/format_like.rs
+++ b/crates/completion/src/completions/postfix/format_like.rs
@@ -88,7 +88,7 @@ enum State {
88} 88}
89 89
90impl FormatStrParser { 90impl FormatStrParser {
91 pub fn new(input: String) -> Self { 91 pub(crate) fn new(input: String) -> Self {
92 Self { 92 Self {
93 input: input.into(), 93 input: input.into(),
94 output: String::new(), 94 output: String::new(),
@@ -98,7 +98,7 @@ impl FormatStrParser {
98 } 98 }
99 } 99 }
100 100
101 pub fn parse(&mut self) -> Result<(), ()> { 101 pub(crate) fn parse(&mut self) -> Result<(), ()> {
102 let mut current_expr = String::new(); 102 let mut current_expr = String::new();
103 103
104 let mut placeholder_id = 1; 104 let mut placeholder_id = 1;
@@ -194,7 +194,7 @@ impl FormatStrParser {
194 Ok(()) 194 Ok(())
195 } 195 }
196 196
197 pub fn into_suggestion(&self, macro_name: &str) -> String { 197 pub(crate) fn into_suggestion(&self, macro_name: &str) -> String {
198 assert!(self.parsed, "Attempt to get a suggestion from not parsed expression"); 198 assert!(self.parsed, "Attempt to get a suggestion from not parsed expression");
199 199
200 let expressions_as_string = self.extracted_expressions.join(", "); 200 let expressions_as_string = self.extracted_expressions.join(", ");
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index 563145f92..30a5e4580 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -4,7 +4,6 @@ use std::{iter, sync::Arc};
4use arrayvec::ArrayVec; 4use arrayvec::ArrayVec;
5use base_db::{CrateDisplayName, CrateId, Edition, FileId}; 5use base_db::{CrateDisplayName, CrateId, Edition, FileId};
6use either::Either; 6use either::Either;
7use hir_def::find_path::PrefixKind;
8use hir_def::{ 7use hir_def::{
9 adt::ReprKind, 8 adt::ReprKind,
10 adt::StructKind, 9 adt::StructKind,
@@ -12,16 +11,18 @@ use hir_def::{
12 builtin_type::BuiltinType, 11 builtin_type::BuiltinType,
13 expr::{BindingAnnotation, Pat, PatId}, 12 expr::{BindingAnnotation, Pat, PatId},
14 import_map, 13 import_map,
14 item_tree::ItemTreeNode,
15 lang_item::LangItemTarget, 15 lang_item::LangItemTarget,
16 path::ModPath, 16 path::ModPath,
17 per_ns::PerNs, 17 per_ns::PerNs,
18 resolver::{HasResolver, Resolver}, 18 resolver::{HasResolver, Resolver},
19 src::HasSource as _, 19 src::HasSource as _,
20 type_ref::{Mutability, TypeRef}, 20 type_ref::{Mutability, TypeRef},
21 AdtId, AssocContainerId, AttrDefId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, 21 AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, DefWithBodyId, EnumId,
22 HasModule, ImplId, LocalEnumVariantId, LocalFieldId, LocalModuleId, Lookup, ModuleId, StaticId, 22 FunctionId, GenericDefId, HasModule, ImplId, LocalEnumVariantId, LocalFieldId, LocalModuleId,
23 StructId, TraitId, TypeAliasId, TypeParamId, UnionId, 23 Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
24}; 24};
25use hir_def::{find_path::PrefixKind, item_scope::ItemInNs, visibility::Visibility};
25use hir_expand::{ 26use hir_expand::{
26 diagnostics::DiagnosticSink, 27 diagnostics::DiagnosticSink,
27 name::{name, AsName}, 28 name::{name, AsName},
@@ -275,11 +276,6 @@ impl ModuleDef {
275 } 276 }
276} 277}
277 278
278pub use hir_def::{
279 attr::Attrs, item_scope::ItemInNs, item_tree::ItemTreeNode, visibility::Visibility,
280 AssocItemId, AssocItemLoc,
281};
282
283impl Module { 279impl Module {
284 pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { 280 pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module {
285 Module { id: ModuleId { krate: krate.id, local_id: crate_module_id } } 281 Module { id: ModuleId { krate: krate.id, local_id: crate_module_id } }
diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs
index 033f53ac2..265ef6d1f 100644
--- a/crates/hir/src/from_id.rs
+++ b/crates/hir/src/from_id.rs
@@ -4,13 +4,13 @@
4//! are splitting the hir. 4//! are splitting the hir.
5 5
6use hir_def::{ 6use hir_def::{
7 expr::PatId, AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, GenericDefId, 7 expr::PatId, item_scope::ItemInNs, AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId,
8 ModuleDefId, VariantId, 8 GenericDefId, ModuleDefId, VariantId,
9}; 9};
10 10
11use crate::{ 11use crate::{
12 code_model::ItemInNs, Adt, AssocItem, DefWithBody, EnumVariant, Field, GenericDef, Local, 12 Adt, AssocItem, DefWithBody, EnumVariant, Field, GenericDef, Local, MacroDef, ModuleDef,
13 MacroDef, ModuleDef, VariantDef, 13 VariantDef,
14}; 14};
15 15
16macro_rules! from_id { 16macro_rules! from_id {
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs
index 3bad2338a..c77494152 100644
--- a/crates/hir/src/has_source.rs
+++ b/crates/hir/src/has_source.rs
@@ -6,6 +6,7 @@ use hir_def::{
6 src::{HasChildSource, HasSource as _}, 6 src::{HasChildSource, HasSource as _},
7 Lookup, VariantId, 7 Lookup, VariantId,
8}; 8};
9use hir_expand::InFile;
9use syntax::ast; 10use syntax::ast;
10 11
11use crate::{ 12use crate::{
@@ -13,8 +14,6 @@ use crate::{
13 Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, 14 Module, Static, Struct, Trait, TypeAlias, TypeParam, Union,
14}; 15};
15 16
16pub use hir_expand::InFile;
17
18pub trait HasSource { 17pub trait HasSource {
19 type Ast; 18 type Ast;
20 fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast>; 19 fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast>;
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 4094a76cb..0d184379f 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -36,7 +36,7 @@ pub use crate::{
36 Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const, 36 Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const,
37 Crate, CrateDependency, DefWithBody, Enum, EnumVariant, Field, FieldSource, Function, 37 Crate, CrateDependency, DefWithBody, Enum, EnumVariant, Field, FieldSource, Function,
38 GenericDef, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, ScopeDef, Static, 38 GenericDef, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, ScopeDef, Static,
39 Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility, 39 Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef,
40 }, 40 },
41 has_source::HasSource, 41 has_source::HasSource,
42 semantics::{original_range, PathResolution, Semantics, SemanticsScope}, 42 semantics::{original_range, PathResolution, Semantics, SemanticsScope},
@@ -53,6 +53,7 @@ pub use hir_def::{
53 nameres::ModuleSource, 53 nameres::ModuleSource,
54 path::{ModPath, PathKind}, 54 path::{ModPath, PathKind},
55 type_ref::{Mutability, TypeRef}, 55 type_ref::{Mutability, TypeRef},
56 visibility::Visibility,
56}; 57};
57pub use hir_expand::{ 58pub use hir_expand::{
58 name::known, name::AsName, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, 59 name::known, name::AsName, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc,
diff --git a/crates/hir_def/src/body/diagnostics.rs b/crates/hir_def/src/body/diagnostics.rs
index cfa47d189..e57bdc133 100644
--- a/crates/hir_def/src/body/diagnostics.rs
+++ b/crates/hir_def/src/body/diagnostics.rs
@@ -5,12 +5,12 @@ use hir_expand::diagnostics::DiagnosticSink;
5use crate::diagnostics::InactiveCode; 5use crate::diagnostics::InactiveCode;
6 6
7#[derive(Debug, Eq, PartialEq)] 7#[derive(Debug, Eq, PartialEq)]
8pub enum BodyDiagnostic { 8pub(crate) enum BodyDiagnostic {
9 InactiveCode(InactiveCode), 9 InactiveCode(InactiveCode),
10} 10}
11 11
12impl BodyDiagnostic { 12impl BodyDiagnostic {
13 pub fn add_to(&self, sink: &mut DiagnosticSink<'_>) { 13 pub(crate) fn add_to(&self, sink: &mut DiagnosticSink<'_>) {
14 match self { 14 match self {
15 BodyDiagnostic::InactiveCode(diag) => { 15 BodyDiagnostic::InactiveCode(diag) => {
16 sink.push(diag.clone()); 16 sink.push(diag.clone());
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index ddc267b83..1deaa90f2 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -45,14 +45,14 @@ pub(crate) struct LowerCtx {
45} 45}
46 46
47impl LowerCtx { 47impl LowerCtx {
48 pub fn new(db: &dyn DefDatabase, file_id: HirFileId) -> Self { 48 pub(crate) fn new(db: &dyn DefDatabase, file_id: HirFileId) -> Self {
49 LowerCtx { hygiene: Hygiene::new(db.upcast(), file_id) } 49 LowerCtx { hygiene: Hygiene::new(db.upcast(), file_id) }
50 } 50 }
51 pub fn with_hygiene(hygiene: &Hygiene) -> Self { 51 pub(crate) fn with_hygiene(hygiene: &Hygiene) -> Self {
52 LowerCtx { hygiene: hygiene.clone() } 52 LowerCtx { hygiene: hygiene.clone() }
53 } 53 }
54 54
55 pub fn lower_path(&self, ast: ast::Path) -> Option<Path> { 55 pub(crate) fn lower_path(&self, ast: ast::Path) -> Option<Path> {
56 Path::from_src(ast, &self.hygiene) 56 Path::from_src(ast, &self.hygiene)
57 } 57 }
58} 58}
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index f24a1dd77..1b22d1eec 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -486,12 +486,12 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
486/// Helper wrapper for `AstId` with `ModPath` 486/// Helper wrapper for `AstId` with `ModPath`
487#[derive(Clone, Debug, Eq, PartialEq)] 487#[derive(Clone, Debug, Eq, PartialEq)]
488struct AstIdWithPath<T: ast::AstNode> { 488struct AstIdWithPath<T: ast::AstNode> {
489 pub ast_id: AstId<T>, 489 ast_id: AstId<T>,
490 pub path: path::ModPath, 490 path: path::ModPath,
491} 491}
492 492
493impl<T: ast::AstNode> AstIdWithPath<T> { 493impl<T: ast::AstNode> AstIdWithPath<T> {
494 pub fn new(file_id: HirFileId, ast_id: FileAstId<T>, path: path::ModPath) -> AstIdWithPath<T> { 494 fn new(file_id: HirFileId, ast_id: FileAstId<T>, path: path::ModPath) -> AstIdWithPath<T> {
495 AstIdWithPath { ast_id: AstId::new(file_id, ast_id), path } 495 AstIdWithPath { ast_id: AstId::new(file_id, ast_id), path }
496 } 496 }
497} 497}
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 1ff45d244..59b6644c3 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -122,13 +122,13 @@ enum ImportSource {
122 122
123#[derive(Clone, Debug, Eq, PartialEq)] 123#[derive(Clone, Debug, Eq, PartialEq)]
124struct Import { 124struct Import {
125 pub path: ModPath, 125 path: ModPath,
126 pub alias: Option<ImportAlias>, 126 alias: Option<ImportAlias>,
127 pub visibility: RawVisibility, 127 visibility: RawVisibility,
128 pub is_glob: bool, 128 is_glob: bool,
129 pub is_prelude: bool, 129 is_prelude: bool,
130 pub is_extern_crate: bool, 130 is_extern_crate: bool,
131 pub is_macro_use: bool, 131 is_macro_use: bool,
132 source: ImportSource, 132 source: ImportSource,
133} 133}
134 134
diff --git a/crates/hir_def/src/test_db.rs b/crates/hir_def/src/test_db.rs
index 2b36c824a..00fe711fe 100644
--- a/crates/hir_def/src/test_db.rs
+++ b/crates/hir_def/src/test_db.rs
@@ -25,7 +25,7 @@ use crate::{db::DefDatabase, ModuleDefId};
25 crate::db::DefDatabaseStorage 25 crate::db::DefDatabaseStorage
26)] 26)]
27#[derive(Default)] 27#[derive(Default)]
28pub struct TestDB { 28pub(crate) struct TestDB {
29 storage: salsa::Storage<TestDB>, 29 storage: salsa::Storage<TestDB>,
30 events: Mutex<Option<Vec<salsa::Event>>>, 30 events: Mutex<Option<Vec<salsa::Event>>>,
31} 31}
@@ -72,7 +72,7 @@ impl FileLoader for TestDB {
72} 72}
73 73
74impl TestDB { 74impl TestDB {
75 pub fn module_for_file(&self, file_id: FileId) -> crate::ModuleId { 75 pub(crate) fn module_for_file(&self, file_id: FileId) -> crate::ModuleId {
76 for &krate in self.relevant_crates(file_id).iter() { 76 for &krate in self.relevant_crates(file_id).iter() {
77 let crate_def_map = self.crate_def_map(krate); 77 let crate_def_map = self.crate_def_map(krate);
78 for (local_id, data) in crate_def_map.modules.iter() { 78 for (local_id, data) in crate_def_map.modules.iter() {
@@ -84,13 +84,13 @@ impl TestDB {
84 panic!("Can't find module for file") 84 panic!("Can't find module for file")
85 } 85 }
86 86
87 pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event> { 87 pub(crate) fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event> {
88 *self.events.lock().unwrap() = Some(Vec::new()); 88 *self.events.lock().unwrap() = Some(Vec::new());
89 f(); 89 f();
90 self.events.lock().unwrap().take().unwrap() 90 self.events.lock().unwrap().take().unwrap()
91 } 91 }
92 92
93 pub fn log_executed(&self, f: impl FnOnce()) -> Vec<String> { 93 pub(crate) fn log_executed(&self, f: impl FnOnce()) -> Vec<String> {
94 let events = self.log(f); 94 let events = self.log(f);
95 events 95 events
96 .into_iter() 96 .into_iter()
@@ -105,7 +105,7 @@ impl TestDB {
105 .collect() 105 .collect()
106 } 106 }
107 107
108 pub fn extract_annotations(&self) -> FxHashMap<FileId, Vec<(TextRange, String)>> { 108 pub(crate) fn extract_annotations(&self) -> FxHashMap<FileId, Vec<(TextRange, String)>> {
109 let mut files = Vec::new(); 109 let mut files = Vec::new();
110 let crate_graph = self.crate_graph(); 110 let crate_graph = self.crate_graph();
111 for krate in crate_graph.iter() { 111 for krate in crate_graph.iter() {
@@ -129,7 +129,7 @@ impl TestDB {
129 .collect() 129 .collect()
130 } 130 }
131 131
132 pub fn diagnostics<F: FnMut(&dyn Diagnostic)>(&self, mut cb: F) { 132 pub(crate) fn diagnostics<F: FnMut(&dyn Diagnostic)>(&self, mut cb: F) {
133 let crate_graph = self.crate_graph(); 133 let crate_graph = self.crate_graph();
134 for krate in crate_graph.iter() { 134 for krate in crate_graph.iter() {
135 let crate_def_map = self.crate_def_map(krate); 135 let crate_def_map = self.crate_def_map(krate);
@@ -148,7 +148,7 @@ impl TestDB {
148 } 148 }
149 } 149 }
150 150
151 pub fn check_diagnostics(&self) { 151 pub(crate) fn check_diagnostics(&self) {
152 let db: &TestDB = self; 152 let db: &TestDB = self;
153 let annotations = db.extract_annotations(); 153 let annotations = db.extract_annotations();
154 assert!(!annotations.is_empty()); 154 assert!(!annotations.is_empty());
diff --git a/crates/hir_expand/src/test_db.rs b/crates/hir_expand/src/test_db.rs
index 86a5d867e..fca501e1f 100644
--- a/crates/hir_expand/src/test_db.rs
+++ b/crates/hir_expand/src/test_db.rs
@@ -14,7 +14,7 @@ use rustc_hash::FxHashSet;
14 crate::db::AstDatabaseStorage 14 crate::db::AstDatabaseStorage
15)] 15)]
16#[derive(Default)] 16#[derive(Default)]
17pub struct TestDB { 17pub(crate) struct TestDB {
18 storage: salsa::Storage<TestDB>, 18 storage: salsa::Storage<TestDB>,
19 events: Mutex<Option<Vec<salsa::Event>>>, 19 events: Mutex<Option<Vec<salsa::Event>>>,
20} 20}
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index 367a1b98d..fdc65a5c3 100644
--- a/crates/hir_ty/Cargo.toml
+++ b/crates/hir_ty/Cargo.toml
@@ -17,9 +17,9 @@ ena = "0.14.0"
17log = "0.4.8" 17log = "0.4.8"
18rustc-hash = "1.1.0" 18rustc-hash = "1.1.0"
19scoped-tls = "1" 19scoped-tls = "1"
20chalk-solve = { version = "0.34", default-features = false } 20chalk-solve = { version = "0.37", default-features = false }
21chalk-ir = "0.34" 21chalk-ir = "0.37"
22chalk-recursive = "0.34" 22chalk-recursive = "0.37"
23 23
24stdx = { path = "../stdx", version = "0.0.0" } 24stdx = { path = "../stdx", version = "0.0.0" }
25hir_def = { path = "../hir_def", version = "0.0.0" } 25hir_def = { path = "../hir_def", version = "0.0.0" }
diff --git a/crates/hir_ty/src/diagnostics/decl_check/case_conv.rs b/crates/hir_ty/src/diagnostics/decl_check/case_conv.rs
index b0144a289..14e4d92f0 100644
--- a/crates/hir_ty/src/diagnostics/decl_check/case_conv.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check/case_conv.rs
@@ -6,7 +6,7 @@
6 6
7/// Converts an identifier to an UpperCamelCase form. 7/// Converts an identifier to an UpperCamelCase form.
8/// Returns `None` if the string is already is UpperCamelCase. 8/// Returns `None` if the string is already is UpperCamelCase.
9pub fn to_camel_case(ident: &str) -> Option<String> { 9pub(crate) fn to_camel_case(ident: &str) -> Option<String> {
10 if is_camel_case(ident) { 10 if is_camel_case(ident) {
11 return None; 11 return None;
12 } 12 }
@@ -59,7 +59,7 @@ pub fn to_camel_case(ident: &str) -> Option<String> {
59 59
60/// Converts an identifier to a lower_snake_case form. 60/// Converts an identifier to a lower_snake_case form.
61/// Returns `None` if the string is already in lower_snake_case. 61/// Returns `None` if the string is already in lower_snake_case.
62pub fn to_lower_snake_case(ident: &str) -> Option<String> { 62pub(crate) fn to_lower_snake_case(ident: &str) -> Option<String> {
63 if is_lower_snake_case(ident) { 63 if is_lower_snake_case(ident) {
64 return None; 64 return None;
65 } else if is_upper_snake_case(ident) { 65 } else if is_upper_snake_case(ident) {
@@ -71,7 +71,7 @@ pub fn to_lower_snake_case(ident: &str) -> Option<String> {
71 71
72/// Converts an identifier to an UPPER_SNAKE_CASE form. 72/// Converts an identifier to an UPPER_SNAKE_CASE form.
73/// Returns `None` if the string is already is UPPER_SNAKE_CASE. 73/// Returns `None` if the string is already is UPPER_SNAKE_CASE.
74pub fn to_upper_snake_case(ident: &str) -> Option<String> { 74pub(crate) fn to_upper_snake_case(ident: &str) -> Option<String> {
75 if is_upper_snake_case(ident) { 75 if is_upper_snake_case(ident) {
76 return None; 76 return None;
77 } else if is_lower_snake_case(ident) { 77 } else if is_lower_snake_case(ident) {
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index 278a4b947..434b19354 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -17,17 +17,10 @@ use crate::{
17 ApplicationTy, InferenceResult, Ty, TypeCtor, 17 ApplicationTy, InferenceResult, Ty, TypeCtor,
18}; 18};
19 19
20pub use hir_def::{ 20pub(crate) use hir_def::{
21 body::{ 21 body::{Body, BodySourceMap},
22 scope::{ExprScopes, ScopeEntry, ScopeId}, 22 expr::{Expr, ExprId, MatchArm, Pat, PatId},
23 Body, BodySourceMap, ExprPtr, ExprSource, PatPtr, PatSource, 23 LocalFieldId, VariantId,
24 },
25 expr::{
26 ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp,
27 MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, UnaryOp,
28 },
29 src::HasSource,
30 LocalFieldId, Lookup, VariantId,
31}; 24};
32 25
33pub(super) struct ExprValidator<'a, 'b: 'a> { 26pub(super) struct ExprValidator<'a, 'b: 'a> {
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs
index 2da9688ca..6dc862826 100644
--- a/crates/hir_ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs
@@ -59,12 +59,12 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> {
59 } 59 }
60} 60}
61 61
62pub struct UnsafeExpr { 62pub(crate) struct UnsafeExpr {
63 pub expr: ExprId, 63 pub(crate) expr: ExprId,
64 pub inside_unsafe_block: bool, 64 pub(crate) inside_unsafe_block: bool,
65} 65}
66 66
67pub fn unsafe_expressions( 67pub(crate) fn unsafe_expressions(
68 db: &dyn HirDatabase, 68 db: &dyn HirDatabase,
69 infer: &InferenceResult, 69 infer: &InferenceResult,
70 def: DefWithBodyId, 70 def: DefWithBodyId,
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index d2e151f25..14e8c0633 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -26,6 +26,20 @@ pub trait HirDisplay {
26 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError>; 26 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError>;
27 27
28 /// Returns a `Display`able type that is human-readable. 28 /// Returns a `Display`able type that is human-readable.
29 fn into_displayable<'a>(
30 &'a self,
31 db: &'a dyn HirDatabase,
32 max_size: Option<usize>,
33 omit_verbose_types: bool,
34 display_target: DisplayTarget,
35 ) -> HirDisplayWrapper<'a, Self>
36 where
37 Self: Sized,
38 {
39 HirDisplayWrapper { db, t: self, max_size, omit_verbose_types, display_target }
40 }
41
42 /// Returns a `Display`able type that is human-readable.
29 /// Use this for showing types to the user (e.g. diagnostics) 43 /// Use this for showing types to the user (e.g. diagnostics)
30 fn display<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self> 44 fn display<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self>
31 where 45 where
@@ -82,6 +96,20 @@ pub trait HirDisplay {
82 }; 96 };
83 Ok(result) 97 Ok(result)
84 } 98 }
99
100 /// Returns a String representation of `self` for test purposes
101 fn display_test<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self>
102 where
103 Self: Sized,
104 {
105 HirDisplayWrapper {
106 db,
107 t: self,
108 max_size: None,
109 omit_verbose_types: false,
110 display_target: DisplayTarget::Test,
111 }
112 }
85} 113}
86 114
87impl<'a> HirFormatter<'a> { 115impl<'a> HirFormatter<'a> {
@@ -126,7 +154,7 @@ impl<'a> HirFormatter<'a> {
126} 154}
127 155
128#[derive(Clone, Copy)] 156#[derive(Clone, Copy)]
129enum DisplayTarget { 157pub enum DisplayTarget {
130 /// Display types for inlays, doc popups, autocompletion, etc... 158 /// Display types for inlays, doc popups, autocompletion, etc...
131 /// Showing `{unknown}` or not qualifying paths is fine here. 159 /// Showing `{unknown}` or not qualifying paths is fine here.
132 /// There's no reason for this to fail. 160 /// There's no reason for this to fail.
@@ -134,12 +162,17 @@ enum DisplayTarget {
134 /// Display types for inserting them in source files. 162 /// Display types for inserting them in source files.
135 /// The generated code should compile, so paths need to be qualified. 163 /// The generated code should compile, so paths need to be qualified.
136 SourceCode { module_id: ModuleId }, 164 SourceCode { module_id: ModuleId },
165 /// Only for test purpose to keep real types
166 Test,
137} 167}
138 168
139impl DisplayTarget { 169impl DisplayTarget {
140 fn is_source_code(&self) -> bool { 170 fn is_source_code(&self) -> bool {
141 matches!(self, Self::SourceCode {..}) 171 matches!(self, Self::SourceCode {..})
142 } 172 }
173 fn is_test(&self) -> bool {
174 matches!(self, Self::Test)
175 }
143} 176}
144 177
145#[derive(Debug)] 178#[derive(Debug)]
@@ -213,32 +246,32 @@ impl HirDisplay for ApplicationTy {
213 TypeCtor::Str => write!(f, "str")?, 246 TypeCtor::Str => write!(f, "str")?,
214 TypeCtor::Slice => { 247 TypeCtor::Slice => {
215 let t = self.parameters.as_single(); 248 let t = self.parameters.as_single();
216 write!(f, "[{}]", t.display(f.db))?; 249 write!(f, "[")?;
250 t.hir_fmt(f)?;
251 write!(f, "]")?;
217 } 252 }
218 TypeCtor::Array => { 253 TypeCtor::Array => {
219 let t = self.parameters.as_single(); 254 let t = self.parameters.as_single();
220 write!(f, "[{}; _]", t.display(f.db))?; 255 write!(f, "[")?;
256 t.hir_fmt(f)?;
257 write!(f, "; _]")?;
221 } 258 }
222 TypeCtor::RawPtr(m) => { 259 TypeCtor::RawPtr(m) => {
223 let t = self.parameters.as_single(); 260 let t = self.parameters.as_single();
224 let ty_display = t.display(f.db);
225 261
226 write!(f, "*{}", m.as_keyword_for_ptr())?; 262 write!(f, "*{}", m.as_keyword_for_ptr())?;
227 if matches!(t, Ty::Dyn(predicates) if predicates.len() > 1) { 263 if matches!(t, Ty::Dyn(predicates) if predicates.len() > 1) {
228 write!(f, "(")?; 264 write!(f, "(")?;
229 write!(f, "{}", ty_display)?; 265 t.hir_fmt(f)?;
230 write!(f, ")")?; 266 write!(f, ")")?;
231 } else { 267 } else {
232 write!(f, "{}", ty_display)?; 268 t.hir_fmt(f)?;
233 } 269 }
234 } 270 }
235 TypeCtor::Ref(m) => { 271 TypeCtor::Ref(m) => {
236 let t = self.parameters.as_single(); 272 let t = self.parameters.as_single();
237 let ty_display = if f.omit_verbose_types() { 273 let ty_display =
238 t.display_truncated(f.db, f.max_size) 274 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
239 } else {
240 t.display(f.db)
241 };
242 275
243 write!(f, "&{}", m.as_keyword_for_ref())?; 276 write!(f, "&{}", m.as_keyword_for_ref())?;
244 if matches!(t, Ty::Dyn(predicates) if predicates.len() > 1) { 277 if matches!(t, Ty::Dyn(predicates) if predicates.len() > 1) {
@@ -253,7 +286,9 @@ impl HirDisplay for ApplicationTy {
253 TypeCtor::Tuple { .. } => { 286 TypeCtor::Tuple { .. } => {
254 let ts = &self.parameters; 287 let ts = &self.parameters;
255 if ts.len() == 1 { 288 if ts.len() == 1 {
256 write!(f, "({},)", ts[0].display(f.db))?; 289 write!(f, "(")?;
290 ts[0].hir_fmt(f)?;
291 write!(f, ",)")?;
257 } else { 292 } else {
258 write!(f, "(")?; 293 write!(f, "(")?;
259 f.write_joined(&*ts.0, ", ")?; 294 f.write_joined(&*ts.0, ", ")?;
@@ -274,11 +309,12 @@ impl HirDisplay for ApplicationTy {
274 write!(f, ")")?; 309 write!(f, ")")?;
275 let ret = sig.ret(); 310 let ret = sig.ret();
276 if *ret != Ty::unit() { 311 if *ret != Ty::unit() {
277 let ret_display = if f.omit_verbose_types() { 312 let ret_display = ret.into_displayable(
278 ret.display_truncated(f.db, f.max_size) 313 f.db,
279 } else { 314 f.max_size,
280 ret.display(f.db) 315 f.omit_verbose_types,
281 }; 316 f.display_target,
317 );
282 write!(f, " -> {}", ret_display)?; 318 write!(f, " -> {}", ret_display)?;
283 } 319 }
284 } 320 }
@@ -310,17 +346,19 @@ impl HirDisplay for ApplicationTy {
310 write!(f, ")")?; 346 write!(f, ")")?;
311 let ret = sig.ret(); 347 let ret = sig.ret();
312 if *ret != Ty::unit() { 348 if *ret != Ty::unit() {
313 let ret_display = if f.omit_verbose_types() { 349 let ret_display = ret.into_displayable(
314 ret.display_truncated(f.db, f.max_size) 350 f.db,
315 } else { 351 f.max_size,
316 ret.display(f.db) 352 f.omit_verbose_types,
317 }; 353 f.display_target,
354 );
355
318 write!(f, " -> {}", ret_display)?; 356 write!(f, " -> {}", ret_display)?;
319 } 357 }
320 } 358 }
321 TypeCtor::Adt(def_id) => { 359 TypeCtor::Adt(def_id) => {
322 match f.display_target { 360 match f.display_target {
323 DisplayTarget::Diagnostics => { 361 DisplayTarget::Diagnostics | DisplayTarget::Test => {
324 let name = match def_id { 362 let name = match def_id {
325 AdtId::StructId(it) => f.db.struct_data(it).name.clone(), 363 AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
326 AdtId::UnionId(it) => f.db.union_data(it).name.clone(), 364 AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
@@ -389,12 +427,23 @@ impl HirDisplay for ApplicationTy {
389 _ => panic!("not an associated type"), 427 _ => panic!("not an associated type"),
390 }; 428 };
391 let trait_ = f.db.trait_data(trait_); 429 let trait_ = f.db.trait_data(trait_);
392 let type_alias = f.db.type_alias_data(type_alias); 430 let type_alias_data = f.db.type_alias_data(type_alias);
393 write!(f, "{}::{}", trait_.name, type_alias.name)?; 431
394 if self.parameters.len() > 0 { 432 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
395 write!(f, "<")?; 433 if f.display_target.is_test() {
396 f.write_joined(&*self.parameters.0, ", ")?; 434 write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
397 write!(f, ">")?; 435 if self.parameters.len() > 0 {
436 write!(f, "<")?;
437 f.write_joined(&*self.parameters.0, ", ")?;
438 write!(f, ">")?;
439 }
440 } else {
441 let projection_ty = ProjectionTy {
442 associated_ty: type_alias,
443 parameters: self.parameters.clone(),
444 };
445
446 projection_ty.hir_fmt(f)?;
398 } 447 }
399 } 448 }
400 TypeCtor::ForeignType(type_alias) => { 449 TypeCtor::ForeignType(type_alias) => {
@@ -439,11 +488,12 @@ impl HirDisplay for ApplicationTy {
439 write!(f, "|")?; 488 write!(f, "|")?;
440 }; 489 };
441 490
442 let ret_display = if f.omit_verbose_types() { 491 let ret_display = sig.ret().into_displayable(
443 sig.ret().display_truncated(f.db, f.max_size) 492 f.db,
444 } else { 493 f.max_size,
445 sig.ret().display(f.db) 494 f.omit_verbose_types,
446 }; 495 f.display_target,
496 );
447 write!(f, " -> {}", ret_display)?; 497 write!(f, " -> {}", ret_display)?;
448 } else { 498 } else {
449 write!(f, "{{closure}}")?; 499 write!(f, "{{closure}}")?;
@@ -461,7 +511,13 @@ impl HirDisplay for ProjectionTy {
461 } 511 }
462 512
463 let trait_ = f.db.trait_data(self.trait_(f.db)); 513 let trait_ = f.db.trait_data(self.trait_(f.db));
464 write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_.name)?; 514 let first_parameter = self.parameters[0].into_displayable(
515 f.db,
516 f.max_size,
517 f.omit_verbose_types,
518 f.display_target,
519 );
520 write!(f, "<{} as {}", first_parameter, trait_.name)?;
465 if self.parameters.len() > 1 { 521 if self.parameters.len() > 1 {
466 write!(f, "<")?; 522 write!(f, "<")?;
467 f.write_joined(&self.parameters[1..], ", ")?; 523 f.write_joined(&self.parameters[1..], ", ")?;
@@ -640,10 +696,10 @@ impl HirDisplay for GenericPredicate {
640 projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?; 696 projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?;
641 write!( 697 write!(
642 f, 698 f,
643 ">::{} = {}", 699 ">::{} = ",
644 f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name, 700 f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name,
645 projection_pred.ty.display(f.db)
646 )?; 701 )?;
702 projection_pred.ty.hir_fmt(f)?;
647 } 703 }
648 GenericPredicate::Error => write!(f, "{{error}}")?, 704 GenericPredicate::Error => write!(f, "{{error}}")?,
649 } 705 }
@@ -654,13 +710,18 @@ impl HirDisplay for GenericPredicate {
654impl HirDisplay for Obligation { 710impl HirDisplay for Obligation {
655 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 711 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
656 match self { 712 match self {
657 Obligation::Trait(tr) => write!(f, "Implements({})", tr.display(f.db)), 713 Obligation::Trait(tr) => {
658 Obligation::Projection(proj) => write!( 714 write!(f, "Implements(")?;
659 f, 715 tr.hir_fmt(f)?;
660 "Normalize({} => {})", 716 write!(f, ")")
661 proj.projection_ty.display(f.db), 717 }
662 proj.ty.display(f.db) 718 Obligation::Projection(proj) => {
663 ), 719 write!(f, "Normalize(")?;
720 proj.projection_ty.hir_fmt(f)?;
721 write!(f, " => ")?;
722 proj.ty.hir_fmt(f)?;
723 write!(f, ")")
724 }
664 } 725 }
665 } 726 }
666} 727}
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 644ebd42d..a14d67c06 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -94,7 +94,7 @@ enum BindingMode {
94} 94}
95 95
96impl BindingMode { 96impl BindingMode {
97 pub fn convert(annotation: BindingAnnotation) -> BindingMode { 97 fn convert(annotation: BindingAnnotation) -> BindingMode {
98 match annotation { 98 match annotation {
99 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move, 99 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move,
100 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Shared), 100 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Shared),
@@ -214,9 +214,9 @@ struct InferenceContext<'a> {
214 214
215#[derive(Clone, Debug)] 215#[derive(Clone, Debug)]
216struct BreakableContext { 216struct BreakableContext {
217 pub may_break: bool, 217 may_break: bool,
218 pub break_ty: Ty, 218 break_ty: Ty,
219 pub label: Option<name::Name>, 219 label: Option<name::Name>,
220} 220}
221 221
222fn find_breakable<'c>( 222fn find_breakable<'c>(
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 8ac4cf89a..605951b10 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -107,7 +107,7 @@ impl<'a> InferenceContext<'a> {
107 } 107 }
108 } 108 }
109 109
110 pub fn callable_sig(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> { 110 pub(crate) fn callable_sig(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> {
111 match ty.callable_sig(self.db) { 111 match ty.callable_sig(self.db) {
112 Some(sig) => Some((sig.params().to_vec(), sig.ret().clone())), 112 Some(sig) => Some((sig.params().to_vec(), sig.ret().clone())),
113 None => self.callable_sig_from_fn_trait(ty, num_args), 113 None => self.callable_sig_from_fn_trait(ty, num_args),
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 2e895d911..76984242e 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -35,7 +35,7 @@ where
35 35
36#[derive(Debug)] 36#[derive(Debug)]
37pub(super) struct Canonicalized<T> { 37pub(super) struct Canonicalized<T> {
38 pub value: Canonical<T>, 38 pub(super) value: Canonical<T>,
39 free_vars: Vec<InferTy>, 39 free_vars: Vec<InferTy>,
40} 40}
41 41
@@ -127,7 +127,7 @@ where
127} 127}
128 128
129impl<T> Canonicalized<T> { 129impl<T> Canonicalized<T> {
130 pub fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { 130 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty {
131 ty.walk_mut_binders( 131 ty.walk_mut_binders(
132 &mut |ty, binders| { 132 &mut |ty, binders| {
133 if let &mut Ty::Bound(bound) = ty { 133 if let &mut Ty::Bound(bound) = ty {
@@ -141,7 +141,11 @@ impl<T> Canonicalized<T> {
141 ty 141 ty
142 } 142 }
143 143
144 pub fn apply_solution(&self, ctx: &mut InferenceContext<'_>, solution: Canonical<Substs>) { 144 pub(super) fn apply_solution(
145 &self,
146 ctx: &mut InferenceContext<'_>,
147 solution: Canonical<Substs>,
148 ) {
145 // the solution may contain new variables, which we need to convert to new inference vars 149 // the solution may contain new variables, which we need to convert to new inference vars
146 let new_vars = Substs( 150 let new_vars = Substs(
147 solution 151 solution
@@ -164,7 +168,7 @@ impl<T> Canonicalized<T> {
164 } 168 }
165} 169}
166 170
167pub fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> { 171pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> {
168 let mut table = InferenceTable::new(); 172 let mut table = InferenceTable::new();
169 let vars = Substs( 173 let vars = Substs(
170 tys.kinds 174 tys.kinds
@@ -199,41 +203,46 @@ pub(crate) struct InferenceTable {
199} 203}
200 204
201impl InferenceTable { 205impl InferenceTable {
202 pub fn new() -> Self { 206 pub(crate) fn new() -> Self {
203 InferenceTable { var_unification_table: InPlaceUnificationTable::new() } 207 InferenceTable { var_unification_table: InPlaceUnificationTable::new() }
204 } 208 }
205 209
206 pub fn new_type_var(&mut self) -> Ty { 210 pub(crate) fn new_type_var(&mut self) -> Ty {
207 Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 211 Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown)))
208 } 212 }
209 213
210 pub fn new_integer_var(&mut self) -> Ty { 214 pub(crate) fn new_integer_var(&mut self) -> Ty {
211 Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 215 Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown)))
212 } 216 }
213 217
214 pub fn new_float_var(&mut self) -> Ty { 218 pub(crate) fn new_float_var(&mut self) -> Ty {
215 Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 219 Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown)))
216 } 220 }
217 221
218 pub fn new_maybe_never_type_var(&mut self) -> Ty { 222 pub(crate) fn new_maybe_never_type_var(&mut self) -> Ty {
219 Ty::Infer(InferTy::MaybeNeverTypeVar( 223 Ty::Infer(InferTy::MaybeNeverTypeVar(
220 self.var_unification_table.new_key(TypeVarValue::Unknown), 224 self.var_unification_table.new_key(TypeVarValue::Unknown),
221 )) 225 ))
222 } 226 }
223 227
224 pub fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { 228 pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty {
225 self.resolve_ty_completely_inner(&mut Vec::new(), ty) 229 self.resolve_ty_completely_inner(&mut Vec::new(), ty)
226 } 230 }
227 231
228 pub fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty { 232 pub(crate) fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty {
229 self.resolve_ty_as_possible_inner(&mut Vec::new(), ty) 233 self.resolve_ty_as_possible_inner(&mut Vec::new(), ty)
230 } 234 }
231 235
232 pub fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 236 pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
233 self.unify_inner(ty1, ty2, 0) 237 self.unify_inner(ty1, ty2, 0)
234 } 238 }
235 239
236 pub fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs, depth: usize) -> bool { 240 pub(crate) fn unify_substs(
241 &mut self,
242 substs1: &Substs,
243 substs2: &Substs,
244 depth: usize,
245 ) -> bool {
237 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) 246 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth))
238 } 247 }
239 248
@@ -331,7 +340,7 @@ impl InferenceTable {
331 340
332 /// If `ty` is a type variable with known type, returns that type; 341 /// If `ty` is a type variable with known type, returns that type;
333 /// otherwise, return ty. 342 /// otherwise, return ty.
334 pub fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { 343 pub(crate) fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> {
335 let mut ty = Cow::Borrowed(ty); 344 let mut ty = Cow::Borrowed(ty);
336 // The type variable could resolve to a int/float variable. Hence try 345 // The type variable could resolve to a int/float variable. Hence try
337 // resolving up to three times; each type of variable shouldn't occur 346 // resolving up to three times; each type of variable shouldn't occur
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 768d95eff..5a8c97198 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -1,6 +1,5 @@
1//! The type system. We currently use this to infer types for completion, hover 1//! The type system. We currently use this to infer types for completion, hover
2//! information and various assists. 2//! information and various assists.
3
4#[allow(unused)] 3#[allow(unused)]
5macro_rules! eprintln { 4macro_rules! eprintln {
6 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) }; 5 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
@@ -1115,5 +1114,5 @@ pub struct ReturnTypeImplTraits {
1115 1114
1116#[derive(Clone, PartialEq, Eq, Debug, Hash)] 1115#[derive(Clone, PartialEq, Eq, Debug, Hash)]
1117pub(crate) struct ReturnTypeImplTrait { 1116pub(crate) struct ReturnTypeImplTrait {
1118 pub bounds: Binders<Vec<GenericPredicate>>, 1117 pub(crate) bounds: Binders<Vec<GenericPredicate>>,
1119} 1118}
diff --git a/crates/hir_ty/src/test_db.rs b/crates/hir_ty/src/test_db.rs
index 15b8435e9..22254b765 100644
--- a/crates/hir_ty/src/test_db.rs
+++ b/crates/hir_ty/src/test_db.rs
@@ -21,7 +21,7 @@ use test_utils::extract_annotations;
21 crate::db::HirDatabaseStorage 21 crate::db::HirDatabaseStorage
22)] 22)]
23#[derive(Default)] 23#[derive(Default)]
24pub struct TestDB { 24pub(crate) struct TestDB {
25 storage: salsa::Storage<TestDB>, 25 storage: salsa::Storage<TestDB>,
26 events: Mutex<Option<Vec<salsa::Event>>>, 26 events: Mutex<Option<Vec<salsa::Event>>>,
27} 27}
@@ -113,13 +113,13 @@ impl TestDB {
113} 113}
114 114
115impl TestDB { 115impl TestDB {
116 pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event> { 116 pub(crate) fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event> {
117 *self.events.lock().unwrap() = Some(Vec::new()); 117 *self.events.lock().unwrap() = Some(Vec::new());
118 f(); 118 f();
119 self.events.lock().unwrap().take().unwrap() 119 self.events.lock().unwrap().take().unwrap()
120 } 120 }
121 121
122 pub fn log_executed(&self, f: impl FnOnce()) -> Vec<String> { 122 pub(crate) fn log_executed(&self, f: impl FnOnce()) -> Vec<String> {
123 let events = self.log(f); 123 let events = self.log(f);
124 events 124 events
125 .into_iter() 125 .into_iter()
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs
index 0445efc9e..104ef334c 100644
--- a/crates/hir_ty/src/tests.rs
+++ b/crates/hir_ty/src/tests.rs
@@ -74,7 +74,7 @@ fn check_types_impl(ra_fixture: &str, display_source: bool) {
74 let module = db.module_for_file(file_id); 74 let module = db.module_for_file(file_id);
75 ty.display_source_code(&db, module).unwrap() 75 ty.display_source_code(&db, module).unwrap()
76 } else { 76 } else {
77 ty.display(&db).to_string() 77 ty.display_test(&db).to_string()
78 }; 78 };
79 assert_eq!(expected, actual); 79 assert_eq!(expected, actual);
80 checked_one = true; 80 checked_one = true;
@@ -163,7 +163,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
163 macro_prefix, 163 macro_prefix,
164 range, 164 range,
165 ellipsize(text, 15), 165 ellipsize(text, 15),
166 ty.display(&db) 166 ty.display_test(&db)
167 ); 167 );
168 } 168 }
169 if include_mismatches { 169 if include_mismatches {
@@ -179,8 +179,8 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
179 "{}{:?}: expected {}, got {}\n", 179 "{}{:?}: expected {}, got {}\n",
180 macro_prefix, 180 macro_prefix,
181 range, 181 range,
182 mismatch.expected.display(&db), 182 mismatch.expected.display_test(&db),
183 mismatch.actual.display(&db), 183 mismatch.actual.display_test(&db),
184 ); 184 );
185 } 185 }
186 } 186 }
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index cbe5cd7dd..55e2c3a3e 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -3,7 +3,7 @@ use std::sync::Arc;
3 3
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg, TypeName}; 6use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg};
7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; 7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
8 8
9use base_db::{salsa::InternKey, CrateId}; 9use base_db::{salsa::InternKey, CrateId};
@@ -27,7 +27,7 @@ use mapping::{
27 TypeAliasAsValue, 27 TypeAliasAsValue,
28}; 28};
29 29
30pub use self::interner::*; 30pub(crate) use self::interner::*;
31 31
32pub(super) mod tls; 32pub(super) mod tls;
33mod interner; 33mod interner;
@@ -81,7 +81,10 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
81 81
82 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone()); 82 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone());
83 83
84 fn binder_kind(ty: &Ty, binders: &CanonicalVarKinds<Interner>) -> Option<chalk_ir::TyKind> { 84 fn binder_kind(
85 ty: &Ty,
86 binders: &CanonicalVarKinds<Interner>,
87 ) -> Option<chalk_ir::TyVariableKind> {
85 if let Ty::Bound(bv) = ty { 88 if let Ty::Bound(bv) = ty {
86 let binders = binders.as_slice(&Interner); 89 let binders = binders.as_slice(&Interner);
87 if bv.debruijn == DebruijnIndex::INNERMOST { 90 if bv.debruijn == DebruijnIndex::INNERMOST {
@@ -95,8 +98,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
95 98
96 let self_ty_fp = TyFingerprint::for_impl(&ty); 99 let self_ty_fp = TyFingerprint::for_impl(&ty);
97 let fps: &[TyFingerprint] = match binder_kind(&ty, binders) { 100 let fps: &[TyFingerprint] = match binder_kind(&ty, binders) {
98 Some(chalk_ir::TyKind::Integer) => &ALL_INT_FPS, 101 Some(chalk_ir::TyVariableKind::Integer) => &ALL_INT_FPS,
99 Some(chalk_ir::TyKind::Float) => &ALL_FLOAT_FPS, 102 Some(chalk_ir::TyVariableKind::Float) => &ALL_FLOAT_FPS,
100 _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]), 103 _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]),
101 }; 104 };
102 105
@@ -129,12 +132,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
129 debug!("impls_for_trait returned {} impls", result.len()); 132 debug!("impls_for_trait returned {} impls", result.len());
130 result 133 result
131 } 134 }
132 fn impl_provided_for( 135 fn impl_provided_for(&self, auto_trait_id: TraitId, kind: &chalk_ir::TyKind<Interner>) -> bool {
133 &self, 136 debug!("impl_provided_for {:?}, {:?}", auto_trait_id, kind);
134 auto_trait_id: TraitId,
135 application_ty: &chalk_ir::ApplicationTy<Interner>,
136 ) -> bool {
137 debug!("impl_provided_for {:?}, {:?}", auto_trait_id, application_ty);
138 false // FIXME 137 false // FIXME
139 } 138 }
140 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> { 139 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> {
@@ -466,7 +465,7 @@ pub(crate) fn struct_datum_query(
466 struct_id: AdtId, 465 struct_id: AdtId,
467) -> Arc<StructDatum> { 466) -> Arc<StructDatum> {
468 debug!("struct_datum {:?}", struct_id); 467 debug!("struct_datum {:?}", struct_id);
469 let type_ctor: TypeCtor = from_chalk(db, TypeName::Adt(struct_id)); 468 let type_ctor = TypeCtor::Adt(from_chalk(db, struct_id));
470 debug!("struct {:?} = {:?}", struct_id, type_ctor); 469 debug!("struct {:?} = {:?}", struct_id, type_ctor);
471 let num_params = type_ctor.num_ty_params(db); 470 let num_params = type_ctor.num_ty_params(db);
472 let upstream = type_ctor.krate(db) != Some(krate); 471 let upstream = type_ctor.krate(db) != Some(krate);
diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/traits/chalk/interner.rs
index f9304b7d0..39569e690 100644
--- a/crates/hir_ty/src/traits/chalk/interner.rs
+++ b/crates/hir_ty/src/traits/chalk/interner.rs
@@ -10,21 +10,21 @@ use std::{fmt, sync::Arc};
10#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] 10#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
11pub struct Interner; 11pub struct Interner;
12 12
13pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>; 13pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
14pub type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; 14pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>;
15pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>; 15pub(crate) type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
16pub type TraitId = chalk_ir::TraitId<Interner>; 16pub(crate) type TraitId = chalk_ir::TraitId<Interner>;
17pub type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>; 17pub(crate) type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>;
18pub type AdtId = chalk_ir::AdtId<Interner>; 18pub(crate) type AdtId = chalk_ir::AdtId<Interner>;
19pub type StructDatum = chalk_solve::rust_ir::AdtDatum<Interner>; 19pub(crate) type StructDatum = chalk_solve::rust_ir::AdtDatum<Interner>;
20pub type ImplId = chalk_ir::ImplId<Interner>; 20pub(crate) type ImplId = chalk_ir::ImplId<Interner>;
21pub type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>; 21pub(crate) type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>;
22pub type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>; 22pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>;
23pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; 23pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>;
24pub type FnDefId = chalk_ir::FnDefId<Interner>; 24pub(crate) type FnDefId = chalk_ir::FnDefId<Interner>;
25pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; 25pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>;
26pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 26pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
27pub type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; 27pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>;
28 28
29impl chalk_ir::interner::Interner for Interner { 29impl chalk_ir::interner::Interner for Interner {
30 type InternedType = Arc<chalk_ir::TyData<Self>>; 30 type InternedType = Arc<chalk_ir::TyData<Self>>;
@@ -122,13 +122,6 @@ impl chalk_ir::interner::Interner for Interner {
122 tls::with_current_program(|prog| Some(prog?.debug_program_clause_implication(pci, fmt))) 122 tls::with_current_program(|prog| Some(prog?.debug_program_clause_implication(pci, fmt)))
123 } 123 }
124 124
125 fn debug_application_ty(
126 application_ty: &chalk_ir::ApplicationTy<Interner>,
127 fmt: &mut fmt::Formatter<'_>,
128 ) -> Option<fmt::Result> {
129 tls::with_current_program(|prog| Some(prog?.debug_application_ty(application_ty, fmt)))
130 }
131
132 fn debug_substitution( 125 fn debug_substitution(
133 substitution: &chalk_ir::Substitution<Interner>, 126 substitution: &chalk_ir::Substitution<Interner>,
134 fmt: &mut fmt::Formatter<'_>, 127 fmt: &mut fmt::Formatter<'_>,
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index dd7affcec..86cbc4c7e 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -5,7 +5,7 @@
5 5
6use chalk_ir::{ 6use chalk_ir::{
7 cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, Scalar, 7 cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, Scalar,
8 TypeName, UniverseIndex, 8 UniverseIndex,
9}; 9};
10use chalk_solve::rust_ir; 10use chalk_solve::rust_ir;
11 11
@@ -32,7 +32,7 @@ impl ToChalk for Ty {
32 TypeCtor::Array => array_to_chalk(db, apply_ty.parameters), 32 TypeCtor::Array => array_to_chalk(db, apply_ty.parameters),
33 TypeCtor::FnPtr { num_args: _, is_varargs } => { 33 TypeCtor::FnPtr { num_args: _, is_varargs } => {
34 let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); 34 let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner);
35 chalk_ir::TyData::Function(chalk_ir::FnPointer { 35 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
36 num_binders: 0, 36 num_binders: 0,
37 sig: chalk_ir::FnSig { 37 sig: chalk_ir::FnSig {
38 abi: (), 38 abi: (),
@@ -43,10 +43,68 @@ impl ToChalk for Ty {
43 }) 43 })
44 .intern(&Interner) 44 .intern(&Interner)
45 } 45 }
46 _ => { 46 TypeCtor::AssociatedType(type_alias) => {
47 let name = apply_ty.ctor.to_chalk(db); 47 let assoc_type = TypeAliasAsAssocType(type_alias);
48 let assoc_type_id = assoc_type.to_chalk(db);
48 let substitution = apply_ty.parameters.to_chalk(db); 49 let substitution = apply_ty.parameters.to_chalk(db);
49 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) 50 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
51 }
52
53 TypeCtor::OpaqueType(impl_trait_id) => {
54 let id = impl_trait_id.to_chalk(db);
55 let substitution = apply_ty.parameters.to_chalk(db);
56 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner)
57 }
58
59 TypeCtor::ForeignType(type_alias) => {
60 let foreign_type = TypeAliasAsForeignType(type_alias);
61 let foreign_type_id = foreign_type.to_chalk(db);
62 chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner)
63 }
64
65 TypeCtor::Bool => chalk_ir::TyKind::Scalar(Scalar::Bool).intern(&Interner),
66 TypeCtor::Char => chalk_ir::TyKind::Scalar(Scalar::Char).intern(&Interner),
67 TypeCtor::Int(int_ty) => {
68 chalk_ir::TyKind::Scalar(int_ty_to_chalk(int_ty)).intern(&Interner)
69 }
70 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => {
71 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F32))
72 .intern(&Interner)
73 }
74 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => {
75 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F64))
76 .intern(&Interner)
77 }
78
79 TypeCtor::Tuple { cardinality } => {
80 let substitution = apply_ty.parameters.to_chalk(db);
81 chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner)
82 }
83 TypeCtor::RawPtr(mutability) => {
84 let ty = apply_ty.parameters[0].clone().to_chalk(db);
85 chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner)
86 }
87 TypeCtor::Slice => {
88 chalk_ir::TyKind::Slice(apply_ty.parameters[0].clone().to_chalk(db))
89 .intern(&Interner)
90 }
91 TypeCtor::Str => chalk_ir::TyKind::Str.intern(&Interner),
92 TypeCtor::FnDef(callable_def) => {
93 let id = callable_def.to_chalk(db);
94 let substitution = apply_ty.parameters.to_chalk(db);
95 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner)
96 }
97 TypeCtor::Never => chalk_ir::TyKind::Never.intern(&Interner),
98
99 TypeCtor::Closure { def, expr } => {
100 let closure_id = db.intern_closure((def, expr));
101 let substitution = apply_ty.parameters.to_chalk(db);
102 chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner)
103 }
104
105 TypeCtor::Adt(adt_id) => {
106 let substitution = apply_ty.parameters.to_chalk(db);
107 chalk_ir::TyKind::Adt(chalk_ir::AdtId(adt_id), substitution).intern(&Interner)
50 } 108 }
51 }, 109 },
52 Ty::Projection(proj_ty) => { 110 Ty::Projection(proj_ty) => {
@@ -67,7 +125,7 @@ impl ToChalk for Ty {
67 } 125 }
68 .to_ty::<Interner>(&Interner) 126 .to_ty::<Interner>(&Interner)
69 } 127 }
70 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner), 128 Ty::Bound(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner),
71 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 129 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
72 Ty::Dyn(predicates) => { 130 Ty::Dyn(predicates) => {
73 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( 131 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
@@ -78,55 +136,45 @@ impl ToChalk for Ty {
78 bounds: make_binders(where_clauses, 1), 136 bounds: make_binders(where_clauses, 1),
79 lifetime: LifetimeData::Static.intern(&Interner), 137 lifetime: LifetimeData::Static.intern(&Interner),
80 }; 138 };
81 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner) 139 chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner)
82 } 140 }
83 Ty::Opaque(opaque_ty) => { 141 Ty::Opaque(opaque_ty) => {
84 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db); 142 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db);
85 let substitution = opaque_ty.parameters.to_chalk(db); 143 let substitution = opaque_ty.parameters.to_chalk(db);
86 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { 144 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
87 opaque_ty_id, 145 opaque_ty_id,
88 substitution, 146 substitution,
89 })) 147 }))
90 .intern(&Interner) 148 .intern(&Interner)
91 } 149 }
92 Ty::Unknown => { 150 Ty::Unknown => chalk_ir::TyKind::Error.intern(&Interner),
93 let substitution = chalk_ir::Substitution::empty(&Interner);
94 let name = TypeName::Error;
95 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
96 }
97 } 151 }
98 } 152 }
99 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { 153 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
100 match chalk.data(&Interner).clone() { 154 match chalk.data(&Interner).kind.clone() {
101 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { 155 chalk_ir::TyKind::Error => Ty::Unknown,
102 TypeName::Error => Ty::Unknown, 156 chalk_ir::TyKind::Array(ty, _size) => {
103 TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution), 157 Ty::apply(TypeCtor::Array, Substs::single(from_chalk(db, ty)))
104 TypeName::Array => array_from_chalk(db, apply_ty.substitution), 158 }
105 _ => { 159 chalk_ir::TyKind::Placeholder(idx) => {
106 let ctor = from_chalk(db, apply_ty.name);
107 let parameters = from_chalk(db, apply_ty.substitution);
108 Ty::Apply(ApplicationTy { ctor, parameters })
109 }
110 },
111 chalk_ir::TyData::Placeholder(idx) => {
112 assert_eq!(idx.ui, UniverseIndex::ROOT); 160 assert_eq!(idx.ui, UniverseIndex::ROOT);
113 let interned_id = crate::db::GlobalTypeParamId::from_intern_id( 161 let interned_id = crate::db::GlobalTypeParamId::from_intern_id(
114 crate::salsa::InternId::from(idx.idx), 162 crate::salsa::InternId::from(idx.idx),
115 ); 163 );
116 Ty::Placeholder(db.lookup_intern_type_param_id(interned_id)) 164 Ty::Placeholder(db.lookup_intern_type_param_id(interned_id))
117 } 165 }
118 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Projection(proj)) => { 166 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => {
119 let associated_ty = 167 let associated_ty =
120 from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0; 168 from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0;
121 let parameters = from_chalk(db, proj.substitution); 169 let parameters = from_chalk(db, proj.substitution);
122 Ty::Projection(ProjectionTy { associated_ty, parameters }) 170 Ty::Projection(ProjectionTy { associated_ty, parameters })
123 } 171 }
124 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => { 172 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => {
125 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id); 173 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id);
126 let parameters = from_chalk(db, opaque_ty.substitution); 174 let parameters = from_chalk(db, opaque_ty.substitution);
127 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) 175 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })
128 } 176 }
129 chalk_ir::TyData::Function(chalk_ir::FnPointer { 177 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
130 num_binders, 178 num_binders,
131 sig: chalk_ir::FnSig { variadic, .. }, 179 sig: chalk_ir::FnSig { variadic, .. },
132 substitution, 180 substitution,
@@ -145,9 +193,9 @@ impl ToChalk for Ty {
145 parameters, 193 parameters,
146 }) 194 })
147 } 195 }
148 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx), 196 chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx),
149 chalk_ir::TyData::InferenceVar(_iv, _kind) => Ty::Unknown, 197 chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown,
150 chalk_ir::TyData::Dyn(where_clauses) => { 198 chalk_ir::TyKind::Dyn(where_clauses) => {
151 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); 199 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1);
152 let predicates = where_clauses 200 let predicates = where_clauses
153 .bounds 201 .bounds
@@ -157,10 +205,76 @@ impl ToChalk for Ty {
157 .collect(); 205 .collect();
158 Ty::Dyn(predicates) 206 Ty::Dyn(predicates)
159 } 207 }
208
209 chalk_ir::TyKind::Adt(struct_id, subst) => {
210 apply_ty_from_chalk(db, TypeCtor::Adt(struct_id.0), subst)
211 }
212 chalk_ir::TyKind::AssociatedType(type_id, subst) => apply_ty_from_chalk(
213 db,
214 TypeCtor::AssociatedType(from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0),
215 subst,
216 ),
217 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => {
218 apply_ty_from_chalk(db, TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)), subst)
219 }
220
221 chalk_ir::TyKind::Scalar(Scalar::Bool) => Ty::simple(TypeCtor::Bool),
222 chalk_ir::TyKind::Scalar(Scalar::Char) => Ty::simple(TypeCtor::Char),
223 chalk_ir::TyKind::Scalar(Scalar::Int(int_ty)) => Ty::simple(TypeCtor::Int(IntTy {
224 signedness: Signedness::Signed,
225 bitness: bitness_from_chalk_int(int_ty),
226 })),
227 chalk_ir::TyKind::Scalar(Scalar::Uint(uint_ty)) => Ty::simple(TypeCtor::Int(IntTy {
228 signedness: Signedness::Unsigned,
229 bitness: bitness_from_chalk_uint(uint_ty),
230 })),
231 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => {
232 Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }))
233 }
234 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => {
235 Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }))
236 }
237 chalk_ir::TyKind::Tuple(cardinality, subst) => {
238 apply_ty_from_chalk(db, TypeCtor::Tuple { cardinality: cardinality as u16 }, subst)
239 }
240 chalk_ir::TyKind::Raw(mutability, ty) => {
241 Ty::apply_one(TypeCtor::RawPtr(from_chalk(db, mutability)), from_chalk(db, ty))
242 }
243 chalk_ir::TyKind::Slice(ty) => Ty::apply_one(TypeCtor::Slice, from_chalk(db, ty)),
244 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => {
245 Ty::apply_one(TypeCtor::Ref(from_chalk(db, mutability)), from_chalk(db, ty))
246 }
247 chalk_ir::TyKind::Str => Ty::simple(TypeCtor::Str),
248 chalk_ir::TyKind::Never => Ty::simple(TypeCtor::Never),
249
250 chalk_ir::TyKind::FnDef(fn_def_id, subst) => {
251 let callable_def = from_chalk(db, fn_def_id);
252 apply_ty_from_chalk(db, TypeCtor::FnDef(callable_def), subst)
253 }
254
255 chalk_ir::TyKind::Closure(id, subst) => {
256 let id: crate::db::ClosureId = id.into();
257 let (def, expr) = db.lookup_intern_closure(id);
258 apply_ty_from_chalk(db, TypeCtor::Closure { def, expr }, subst)
259 }
260
261 chalk_ir::TyKind::Foreign(foreign_def_id) => Ty::simple(TypeCtor::ForeignType(
262 from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0,
263 )),
264 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME
265 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME
160 } 266 }
161 } 267 }
162} 268}
163 269
270fn apply_ty_from_chalk(
271 db: &dyn HirDatabase,
272 ctor: TypeCtor,
273 subst: chalk_ir::Substitution<Interner>,
274) -> Ty {
275 Ty::Apply(ApplicationTy { ctor, parameters: from_chalk(db, subst) })
276}
277
164/// We currently don't model lifetimes, but Chalk does. So, we have to insert a 278/// We currently don't model lifetimes, but Chalk does. So, we have to insert a
165/// fake lifetime here, because Chalks built-in logic may expect it to be there. 279/// fake lifetime here, because Chalks built-in logic may expect it to be there.
166fn ref_to_chalk( 280fn ref_to_chalk(
@@ -170,60 +284,21 @@ fn ref_to_chalk(
170) -> chalk_ir::Ty<Interner> { 284) -> chalk_ir::Ty<Interner> {
171 let arg = subst[0].clone().to_chalk(db); 285 let arg = subst[0].clone().to_chalk(db);
172 let lifetime = LifetimeData::Static.intern(&Interner); 286 let lifetime = LifetimeData::Static.intern(&Interner);
173 chalk_ir::ApplicationTy { 287 chalk_ir::TyKind::Ref(mutability.to_chalk(db), lifetime, arg).intern(&Interner)
174 name: TypeName::Ref(mutability.to_chalk(db)),
175 substitution: chalk_ir::Substitution::from_iter(
176 &Interner,
177 vec![lifetime.cast(&Interner), arg.cast(&Interner)],
178 ),
179 }
180 .intern(&Interner)
181}
182
183/// Here we remove the lifetime from the type we got from Chalk.
184fn ref_from_chalk(
185 db: &dyn HirDatabase,
186 mutability: chalk_ir::Mutability,
187 subst: chalk_ir::Substitution<Interner>,
188) -> Ty {
189 let tys = subst
190 .iter(&Interner)
191 .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone())))
192 .collect();
193 Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys))
194} 288}
195 289
196/// We currently don't model constants, but Chalk does. So, we have to insert a 290/// We currently don't model constants, but Chalk does. So, we have to insert a
197/// fake constant here, because Chalks built-in logic may expect it to be there. 291/// fake constant here, because Chalks built-in logic may expect it to be there.
198fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> { 292fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> {
199 let arg = subst[0].clone().to_chalk(db); 293 let arg = subst[0].clone().to_chalk(db);
200 let usize_ty = chalk_ir::ApplicationTy { 294 let usize_ty =
201 name: TypeName::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)), 295 chalk_ir::TyKind::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)).intern(&Interner);
202 substitution: chalk_ir::Substitution::empty(&Interner),
203 }
204 .intern(&Interner);
205 let const_ = chalk_ir::ConstData { 296 let const_ = chalk_ir::ConstData {
206 ty: usize_ty, 297 ty: usize_ty,
207 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }), 298 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }),
208 } 299 }
209 .intern(&Interner); 300 .intern(&Interner);
210 chalk_ir::ApplicationTy { 301 chalk_ir::TyKind::Array(arg, const_).intern(&Interner)
211 name: TypeName::Array,
212 substitution: chalk_ir::Substitution::from_iter(
213 &Interner,
214 vec![arg.cast(&Interner), const_.cast(&Interner)],
215 ),
216 }
217 .intern(&Interner)
218}
219
220/// Here we remove the const from the type we got from Chalk.
221fn array_from_chalk(db: &dyn HirDatabase, subst: chalk_ir::Substitution<Interner>) -> Ty {
222 let tys = subst
223 .iter(&Interner)
224 .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone())))
225 .collect();
226 Ty::apply(TypeCtor::Array, Substs(tys))
227} 302}
228 303
229impl ToChalk for Substs { 304impl ToChalk for Substs {
@@ -288,124 +363,6 @@ impl ToChalk for OpaqueTyId {
288 } 363 }
289} 364}
290 365
291impl ToChalk for TypeCtor {
292 type Chalk = TypeName<Interner>;
293
294 fn to_chalk(self, db: &dyn HirDatabase) -> TypeName<Interner> {
295 match self {
296 TypeCtor::AssociatedType(type_alias) => {
297 let assoc_type = TypeAliasAsAssocType(type_alias);
298 let assoc_type_id = assoc_type.to_chalk(db);
299 TypeName::AssociatedType(assoc_type_id)
300 }
301
302 TypeCtor::OpaqueType(impl_trait_id) => {
303 let id = impl_trait_id.to_chalk(db);
304 TypeName::OpaqueType(id)
305 }
306
307 TypeCtor::ForeignType(type_alias) => {
308 let foreign_type = TypeAliasAsForeignType(type_alias);
309 let foreign_type_id = foreign_type.to_chalk(db);
310 TypeName::Foreign(foreign_type_id)
311 }
312
313 TypeCtor::Bool => TypeName::Scalar(Scalar::Bool),
314 TypeCtor::Char => TypeName::Scalar(Scalar::Char),
315 TypeCtor::Int(int_ty) => TypeName::Scalar(int_ty_to_chalk(int_ty)),
316 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => {
317 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32))
318 }
319 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => {
320 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64))
321 }
322
323 TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()),
324 TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)),
325 TypeCtor::Slice => TypeName::Slice,
326 TypeCtor::Array => TypeName::Array,
327 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
328 TypeCtor::Str => TypeName::Str,
329 TypeCtor::FnDef(callable_def) => {
330 let id = callable_def.to_chalk(db);
331 TypeName::FnDef(id)
332 }
333 TypeCtor::Never => TypeName::Never,
334
335 TypeCtor::Closure { def, expr } => {
336 let closure_id = db.intern_closure((def, expr));
337 TypeName::Closure(closure_id.into())
338 }
339
340 TypeCtor::Adt(adt_id) => TypeName::Adt(chalk_ir::AdtId(adt_id)),
341
342 TypeCtor::FnPtr { .. } => {
343 // This should not be reached, since Chalk doesn't represent
344 // function pointers with TypeName
345 unreachable!()
346 }
347 }
348 }
349
350 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor {
351 match type_name {
352 TypeName::Adt(struct_id) => TypeCtor::Adt(struct_id.0),
353 TypeName::AssociatedType(type_id) => {
354 TypeCtor::AssociatedType(from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0)
355 }
356 TypeName::OpaqueType(opaque_type_id) => {
357 TypeCtor::OpaqueType(from_chalk(db, opaque_type_id))
358 }
359
360 TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool,
361 TypeName::Scalar(Scalar::Char) => TypeCtor::Char,
362 TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(IntTy {
363 signedness: Signedness::Signed,
364 bitness: bitness_from_chalk_int(int_ty),
365 }),
366 TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(IntTy {
367 signedness: Signedness::Unsigned,
368 bitness: bitness_from_chalk_uint(uint_ty),
369 }),
370 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => {
371 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })
372 }
373 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => {
374 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })
375 }
376 TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 },
377 TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)),
378 TypeName::Slice => TypeCtor::Slice,
379 TypeName::Ref(mutability) => TypeCtor::Ref(from_chalk(db, mutability)),
380 TypeName::Str => TypeCtor::Str,
381 TypeName::Never => TypeCtor::Never,
382
383 TypeName::FnDef(fn_def_id) => {
384 let callable_def = from_chalk(db, fn_def_id);
385 TypeCtor::FnDef(callable_def)
386 }
387 TypeName::Array => TypeCtor::Array,
388
389 TypeName::Closure(id) => {
390 let id: crate::db::ClosureId = id.into();
391 let (def, expr) = db.lookup_intern_closure(id);
392 TypeCtor::Closure { def, expr }
393 }
394
395 TypeName::Foreign(foreign_def_id) => {
396 TypeCtor::ForeignType(from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0)
397 }
398
399 TypeName::Error => {
400 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
401 unreachable!()
402 }
403 TypeName::Generator(_) => unimplemented!(), // FIXME
404 TypeName::GeneratorWitness(_) => unimplemented!(), // FIXME
405 }
406 }
407}
408
409fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness { 366fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness {
410 use chalk_ir::UintTy; 367 use chalk_ir::UintTy;
411 368
@@ -507,7 +464,7 @@ impl ToChalk for CallableDefId {
507 } 464 }
508} 465}
509 466
510pub struct TypeAliasAsAssocType(pub TypeAliasId); 467pub(crate) struct TypeAliasAsAssocType(pub(crate) TypeAliasId);
511 468
512impl ToChalk for TypeAliasAsAssocType { 469impl ToChalk for TypeAliasAsAssocType {
513 type Chalk = AssocTypeId; 470 type Chalk = AssocTypeId;
@@ -521,7 +478,7 @@ impl ToChalk for TypeAliasAsAssocType {
521 } 478 }
522} 479}
523 480
524pub struct TypeAliasAsForeignType(pub TypeAliasId); 481pub(crate) struct TypeAliasAsForeignType(pub(crate) TypeAliasId);
525 482
526impl ToChalk for TypeAliasAsForeignType { 483impl ToChalk for TypeAliasAsForeignType {
527 type Chalk = ForeignDefId; 484 type Chalk = ForeignDefId;
@@ -535,7 +492,7 @@ impl ToChalk for TypeAliasAsForeignType {
535 } 492 }
536} 493}
537 494
538pub struct TypeAliasAsValue(pub TypeAliasId); 495pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId);
539 496
540impl ToChalk for TypeAliasAsValue { 497impl ToChalk for TypeAliasAsValue {
541 type Chalk = AssociatedTyValueId; 498 type Chalk = AssociatedTyValueId;
@@ -677,9 +634,9 @@ where
677 .kinds 634 .kinds
678 .iter() 635 .iter()
679 .map(|k| match k { 636 .map(|k| match k {
680 TyKind::General => chalk_ir::TyKind::General, 637 TyKind::General => chalk_ir::TyVariableKind::General,
681 TyKind::Integer => chalk_ir::TyKind::Integer, 638 TyKind::Integer => chalk_ir::TyVariableKind::Integer,
682 TyKind::Float => chalk_ir::TyKind::Float, 639 TyKind::Float => chalk_ir::TyVariableKind::Float,
683 }) 640 })
684 .map(|tk| { 641 .map(|tk| {
685 chalk_ir::CanonicalVarKind::new( 642 chalk_ir::CanonicalVarKind::new(
@@ -700,9 +657,9 @@ where
700 .iter(&Interner) 657 .iter(&Interner)
701 .map(|k| match k.kind { 658 .map(|k| match k.kind {
702 chalk_ir::VariableKind::Ty(tk) => match tk { 659 chalk_ir::VariableKind::Ty(tk) => match tk {
703 chalk_ir::TyKind::General => TyKind::General, 660 chalk_ir::TyVariableKind::General => TyKind::General,
704 chalk_ir::TyKind::Integer => TyKind::Integer, 661 chalk_ir::TyVariableKind::Integer => TyKind::Integer,
705 chalk_ir::TyKind::Float => TyKind::Float, 662 chalk_ir::TyVariableKind::Float => TyKind::Float,
706 }, 663 },
707 chalk_ir::VariableKind::Lifetime => panic!("unexpected lifetime from Chalk"), 664 chalk_ir::VariableKind::Lifetime => panic!("unexpected lifetime from Chalk"),
708 chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"), 665 chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"),
@@ -768,7 +725,8 @@ where
768 chalk_ir::Binders::new( 725 chalk_ir::Binders::new(
769 chalk_ir::VariableKinds::from_iter( 726 chalk_ir::VariableKinds::from_iter(
770 &Interner, 727 &Interner,
771 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars), 728 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
729 .take(num_vars),
772 ), 730 ),
773 value, 731 value,
774 ) 732 )
diff --git a/crates/hir_ty/src/traits/chalk/tls.rs b/crates/hir_ty/src/traits/chalk/tls.rs
index b4568cff6..75b16172e 100644
--- a/crates/hir_ty/src/traits/chalk/tls.rs
+++ b/crates/hir_ty/src/traits/chalk/tls.rs
@@ -1,114 +1,32 @@
1//! Implementation of Chalk debug helper functions using TLS. 1//! Implementation of Chalk debug helper functions using TLS.
2use std::fmt; 2use std::fmt;
3 3
4use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication, TypeName}; 4use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication};
5use itertools::Itertools; 5use itertools::Itertools;
6 6
7use super::{from_chalk, Interner, TypeAliasAsAssocType}; 7use super::{from_chalk, Interner, TypeAliasAsAssocType};
8use crate::{db::HirDatabase, CallableDefId, TypeCtor}; 8use crate::{db::HirDatabase, CallableDefId};
9use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId}; 9use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId};
10 10
11pub use unsafe_tls::{set_current_program, with_current_program}; 11pub(crate) use unsafe_tls::{set_current_program, with_current_program};
12 12
13pub struct DebugContext<'a>(&'a dyn HirDatabase); 13pub(crate) struct DebugContext<'a>(&'a dyn HirDatabase);
14 14
15impl DebugContext<'_> { 15impl DebugContext<'_> {
16 pub fn debug_struct_id( 16 pub(crate) fn debug_struct_id(
17 &self, 17 &self,
18 id: super::AdtId, 18 id: super::AdtId,
19 f: &mut fmt::Formatter<'_>, 19 f: &mut fmt::Formatter<'_>,
20 ) -> Result<(), fmt::Error> { 20 ) -> Result<(), fmt::Error> {
21 let type_ctor: TypeCtor = from_chalk(self.0, TypeName::Adt(id)); 21 let name = match id.0 {
22 match type_ctor { 22 AdtId::StructId(it) => self.0.struct_data(it).name.clone(),
23 TypeCtor::Bool => write!(f, "bool")?, 23 AdtId::UnionId(it) => self.0.union_data(it).name.clone(),
24 TypeCtor::Char => write!(f, "char")?, 24 AdtId::EnumId(it) => self.0.enum_data(it).name.clone(),
25 TypeCtor::Int(t) => write!(f, "{}", t)?, 25 };
26 TypeCtor::Float(t) => write!(f, "{}", t)?, 26 write!(f, "{}", name)
27 TypeCtor::Str => write!(f, "str")?,
28 TypeCtor::Slice => write!(f, "slice")?,
29 TypeCtor::Array => write!(f, "array")?,
30 TypeCtor::RawPtr(m) => write!(f, "*{}", m.as_keyword_for_ptr())?,
31 TypeCtor::Ref(m) => write!(f, "&{}", m.as_keyword_for_ref())?,
32 TypeCtor::Never => write!(f, "!")?,
33 TypeCtor::Tuple { .. } => {
34 write!(f, "()")?;
35 }
36 TypeCtor::FnPtr { .. } => {
37 write!(f, "fn")?;
38 }
39 TypeCtor::FnDef(def) => {
40 let name = match def {
41 CallableDefId::FunctionId(ff) => self.0.function_data(ff).name.clone(),
42 CallableDefId::StructId(s) => self.0.struct_data(s).name.clone(),
43 CallableDefId::EnumVariantId(e) => {
44 let enum_data = self.0.enum_data(e.parent);
45 enum_data.variants[e.local_id].name.clone()
46 }
47 };
48 match def {
49 CallableDefId::FunctionId(_) => write!(f, "{{fn {}}}", name)?,
50 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {
51 write!(f, "{{ctor {}}}", name)?
52 }
53 }
54 }
55 TypeCtor::Adt(def_id) => {
56 let name = match def_id {
57 AdtId::StructId(it) => self.0.struct_data(it).name.clone(),
58 AdtId::UnionId(it) => self.0.union_data(it).name.clone(),
59 AdtId::EnumId(it) => self.0.enum_data(it).name.clone(),
60 };
61 write!(f, "{}", name)?;
62 }
63 TypeCtor::AssociatedType(type_alias) => {
64 let trait_ = match type_alias.lookup(self.0.upcast()).container {
65 AssocContainerId::TraitId(it) => it,
66 _ => panic!("not an associated type"),
67 };
68 let trait_name = self.0.trait_data(trait_).name.clone();
69 let name = self.0.type_alias_data(type_alias).name.clone();
70 write!(f, "{}::{}", trait_name, name)?;
71 }
72 TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id {
73 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
74 write!(f, "{{impl trait {} of {:?}}}", idx, func)?;
75 }
76 crate::OpaqueTyId::AsyncBlockTypeImplTrait(def, idx) => {
77 write!(f, "{{impl trait of async block {} of {:?}}}", idx.into_raw(), def)?;
78 }
79 },
80 TypeCtor::ForeignType(type_alias) => {
81 let name = self.0.type_alias_data(type_alias).name.clone();
82 write!(f, "{}", name)?;
83 }
84 TypeCtor::Closure { def, expr } => {
85 write!(f, "{{closure {:?} in ", expr.into_raw())?;
86 match def {
87 DefWithBodyId::FunctionId(func) => {
88 write!(f, "fn {}", self.0.function_data(func).name)?
89 }
90 DefWithBodyId::StaticId(s) => {
91 if let Some(name) = self.0.static_data(s).name.as_ref() {
92 write!(f, "body of static {}", name)?;
93 } else {
94 write!(f, "body of unnamed static {:?}", s)?;
95 }
96 }
97 DefWithBodyId::ConstId(c) => {
98 if let Some(name) = self.0.const_data(c).name.as_ref() {
99 write!(f, "body of const {}", name)?;
100 } else {
101 write!(f, "body of unnamed const {:?}", c)?;
102 }
103 }
104 };
105 write!(f, "}}")?;
106 }
107 }
108 Ok(())
109 } 27 }
110 28
111 pub fn debug_trait_id( 29 pub(crate) fn debug_trait_id(
112 &self, 30 &self,
113 id: super::TraitId, 31 id: super::TraitId,
114 fmt: &mut fmt::Formatter<'_>, 32 fmt: &mut fmt::Formatter<'_>,
@@ -118,7 +36,7 @@ impl DebugContext<'_> {
118 write!(fmt, "{}", trait_data.name) 36 write!(fmt, "{}", trait_data.name)
119 } 37 }
120 38
121 pub fn debug_assoc_type_id( 39 pub(crate) fn debug_assoc_type_id(
122 &self, 40 &self,
123 id: super::AssocTypeId, 41 id: super::AssocTypeId,
124 fmt: &mut fmt::Formatter<'_>, 42 fmt: &mut fmt::Formatter<'_>,
@@ -133,7 +51,7 @@ impl DebugContext<'_> {
133 write!(fmt, "{}::{}", trait_data.name, type_alias_data.name) 51 write!(fmt, "{}::{}", trait_data.name, type_alias_data.name)
134 } 52 }
135 53
136 pub fn debug_opaque_ty_id( 54 pub(crate) fn debug_opaque_ty_id(
137 &self, 55 &self,
138 opaque_ty_id: chalk_ir::OpaqueTyId<Interner>, 56 opaque_ty_id: chalk_ir::OpaqueTyId<Interner>,
139 fmt: &mut fmt::Formatter<'_>, 57 fmt: &mut fmt::Formatter<'_>,
@@ -141,7 +59,7 @@ impl DebugContext<'_> {
141 fmt.debug_struct("OpaqueTyId").field("index", &opaque_ty_id.0).finish() 59 fmt.debug_struct("OpaqueTyId").field("index", &opaque_ty_id.0).finish()
142 } 60 }
143 61
144 pub fn debug_alias( 62 pub(crate) fn debug_alias(
145 &self, 63 &self,
146 alias_ty: &AliasTy<Interner>, 64 alias_ty: &AliasTy<Interner>,
147 fmt: &mut fmt::Formatter<'_>, 65 fmt: &mut fmt::Formatter<'_>,
@@ -152,7 +70,7 @@ impl DebugContext<'_> {
152 } 70 }
153 } 71 }
154 72
155 pub fn debug_projection_ty( 73 pub(crate) fn debug_projection_ty(
156 &self, 74 &self,
157 projection_ty: &chalk_ir::ProjectionTy<Interner>, 75 projection_ty: &chalk_ir::ProjectionTy<Interner>,
158 fmt: &mut fmt::Formatter<'_>, 76 fmt: &mut fmt::Formatter<'_>,
@@ -177,7 +95,7 @@ impl DebugContext<'_> {
177 write!(fmt, ">::{}", type_alias_data.name) 95 write!(fmt, ">::{}", type_alias_data.name)
178 } 96 }
179 97
180 pub fn debug_opaque_ty( 98 pub(crate) fn debug_opaque_ty(
181 &self, 99 &self,
182 opaque_ty: &chalk_ir::OpaqueTy<Interner>, 100 opaque_ty: &chalk_ir::OpaqueTy<Interner>,
183 fmt: &mut fmt::Formatter<'_>, 101 fmt: &mut fmt::Formatter<'_>,
@@ -185,7 +103,7 @@ impl DebugContext<'_> {
185 write!(fmt, "{:?}", opaque_ty.opaque_ty_id) 103 write!(fmt, "{:?}", opaque_ty.opaque_ty_id)
186 } 104 }
187 105
188 pub fn debug_ty( 106 pub(crate) fn debug_ty(
189 &self, 107 &self,
190 ty: &chalk_ir::Ty<Interner>, 108 ty: &chalk_ir::Ty<Interner>,
191 fmt: &mut fmt::Formatter<'_>, 109 fmt: &mut fmt::Formatter<'_>,
@@ -193,7 +111,7 @@ impl DebugContext<'_> {
193 write!(fmt, "{:?}", ty.data(&Interner)) 111 write!(fmt, "{:?}", ty.data(&Interner))
194 } 112 }
195 113
196 pub fn debug_lifetime( 114 pub(crate) fn debug_lifetime(
197 &self, 115 &self,
198 lifetime: &Lifetime<Interner>, 116 lifetime: &Lifetime<Interner>,
199 fmt: &mut fmt::Formatter<'_>, 117 fmt: &mut fmt::Formatter<'_>,
@@ -201,7 +119,7 @@ impl DebugContext<'_> {
201 write!(fmt, "{:?}", lifetime.data(&Interner)) 119 write!(fmt, "{:?}", lifetime.data(&Interner))
202 } 120 }
203 121
204 pub fn debug_generic_arg( 122 pub(crate) fn debug_generic_arg(
205 &self, 123 &self,
206 parameter: &GenericArg<Interner>, 124 parameter: &GenericArg<Interner>,
207 fmt: &mut fmt::Formatter<'_>, 125 fmt: &mut fmt::Formatter<'_>,
@@ -209,7 +127,7 @@ impl DebugContext<'_> {
209 write!(fmt, "{:?}", parameter.data(&Interner).inner_debug()) 127 write!(fmt, "{:?}", parameter.data(&Interner).inner_debug())
210 } 128 }
211 129
212 pub fn debug_goal( 130 pub(crate) fn debug_goal(
213 &self, 131 &self,
214 goal: &Goal<Interner>, 132 goal: &Goal<Interner>,
215 fmt: &mut fmt::Formatter<'_>, 133 fmt: &mut fmt::Formatter<'_>,
@@ -218,7 +136,7 @@ impl DebugContext<'_> {
218 write!(fmt, "{:?}", goal_data) 136 write!(fmt, "{:?}", goal_data)
219 } 137 }
220 138
221 pub fn debug_goals( 139 pub(crate) fn debug_goals(
222 &self, 140 &self,
223 goals: &Goals<Interner>, 141 goals: &Goals<Interner>,
224 fmt: &mut fmt::Formatter<'_>, 142 fmt: &mut fmt::Formatter<'_>,
@@ -226,7 +144,7 @@ impl DebugContext<'_> {
226 write!(fmt, "{:?}", goals.debug(&Interner)) 144 write!(fmt, "{:?}", goals.debug(&Interner))
227 } 145 }
228 146
229 pub fn debug_program_clause_implication( 147 pub(crate) fn debug_program_clause_implication(
230 &self, 148 &self,
231 pci: &ProgramClauseImplication<Interner>, 149 pci: &ProgramClauseImplication<Interner>,
232 fmt: &mut fmt::Formatter<'_>, 150 fmt: &mut fmt::Formatter<'_>,
@@ -234,15 +152,7 @@ impl DebugContext<'_> {
234 write!(fmt, "{:?}", pci.debug(&Interner)) 152 write!(fmt, "{:?}", pci.debug(&Interner))
235 } 153 }
236 154
237 pub fn debug_application_ty( 155 pub(crate) fn debug_substitution(
238 &self,
239 application_ty: &chalk_ir::ApplicationTy<Interner>,
240 fmt: &mut fmt::Formatter<'_>,
241 ) -> Result<(), fmt::Error> {
242 write!(fmt, "{:?}", application_ty.debug(&Interner))
243 }
244
245 pub fn debug_substitution(
246 &self, 156 &self,
247 substitution: &chalk_ir::Substitution<Interner>, 157 substitution: &chalk_ir::Substitution<Interner>,
248 fmt: &mut fmt::Formatter<'_>, 158 fmt: &mut fmt::Formatter<'_>,
@@ -250,7 +160,7 @@ impl DebugContext<'_> {
250 write!(fmt, "{:?}", substitution.debug(&Interner)) 160 write!(fmt, "{:?}", substitution.debug(&Interner))
251 } 161 }
252 162
253 pub fn debug_separator_trait_ref( 163 pub(crate) fn debug_separator_trait_ref(
254 &self, 164 &self,
255 separator_trait_ref: &chalk_ir::SeparatorTraitRef<Interner>, 165 separator_trait_ref: &chalk_ir::SeparatorTraitRef<Interner>,
256 fmt: &mut fmt::Formatter<'_>, 166 fmt: &mut fmt::Formatter<'_>,
@@ -258,7 +168,7 @@ impl DebugContext<'_> {
258 write!(fmt, "{:?}", separator_trait_ref.debug(&Interner)) 168 write!(fmt, "{:?}", separator_trait_ref.debug(&Interner))
259 } 169 }
260 170
261 pub fn debug_fn_def_id( 171 pub(crate) fn debug_fn_def_id(
262 &self, 172 &self,
263 fn_def_id: chalk_ir::FnDefId<Interner>, 173 fn_def_id: chalk_ir::FnDefId<Interner>,
264 fmt: &mut fmt::Formatter<'_>, 174 fmt: &mut fmt::Formatter<'_>,
@@ -280,7 +190,7 @@ impl DebugContext<'_> {
280 } 190 }
281 } 191 }
282 192
283 pub fn debug_const( 193 pub(crate) fn debug_const(
284 &self, 194 &self,
285 _constant: &chalk_ir::Const<Interner>, 195 _constant: &chalk_ir::Const<Interner>,
286 fmt: &mut fmt::Formatter<'_>, 196 fmt: &mut fmt::Formatter<'_>,
@@ -288,42 +198,42 @@ impl DebugContext<'_> {
288 write!(fmt, "const") 198 write!(fmt, "const")
289 } 199 }
290 200
291 pub fn debug_variable_kinds( 201 pub(crate) fn debug_variable_kinds(
292 &self, 202 &self,
293 variable_kinds: &chalk_ir::VariableKinds<Interner>, 203 variable_kinds: &chalk_ir::VariableKinds<Interner>,
294 fmt: &mut fmt::Formatter<'_>, 204 fmt: &mut fmt::Formatter<'_>,
295 ) -> fmt::Result { 205 ) -> fmt::Result {
296 write!(fmt, "{:?}", variable_kinds.as_slice(&Interner)) 206 write!(fmt, "{:?}", variable_kinds.as_slice(&Interner))
297 } 207 }
298 pub fn debug_variable_kinds_with_angles( 208 pub(crate) fn debug_variable_kinds_with_angles(
299 &self, 209 &self,
300 variable_kinds: &chalk_ir::VariableKinds<Interner>, 210 variable_kinds: &chalk_ir::VariableKinds<Interner>,
301 fmt: &mut fmt::Formatter<'_>, 211 fmt: &mut fmt::Formatter<'_>,
302 ) -> fmt::Result { 212 ) -> fmt::Result {
303 write!(fmt, "{:?}", variable_kinds.inner_debug(&Interner)) 213 write!(fmt, "{:?}", variable_kinds.inner_debug(&Interner))
304 } 214 }
305 pub fn debug_canonical_var_kinds( 215 pub(crate) fn debug_canonical_var_kinds(
306 &self, 216 &self,
307 canonical_var_kinds: &chalk_ir::CanonicalVarKinds<Interner>, 217 canonical_var_kinds: &chalk_ir::CanonicalVarKinds<Interner>,
308 fmt: &mut fmt::Formatter<'_>, 218 fmt: &mut fmt::Formatter<'_>,
309 ) -> fmt::Result { 219 ) -> fmt::Result {
310 write!(fmt, "{:?}", canonical_var_kinds.as_slice(&Interner)) 220 write!(fmt, "{:?}", canonical_var_kinds.as_slice(&Interner))
311 } 221 }
312 pub fn debug_program_clause( 222 pub(crate) fn debug_program_clause(
313 &self, 223 &self,
314 clause: &chalk_ir::ProgramClause<Interner>, 224 clause: &chalk_ir::ProgramClause<Interner>,
315 fmt: &mut fmt::Formatter<'_>, 225 fmt: &mut fmt::Formatter<'_>,
316 ) -> fmt::Result { 226 ) -> fmt::Result {
317 write!(fmt, "{:?}", clause.data(&Interner)) 227 write!(fmt, "{:?}", clause.data(&Interner))
318 } 228 }
319 pub fn debug_program_clauses( 229 pub(crate) fn debug_program_clauses(
320 &self, 230 &self,
321 clauses: &chalk_ir::ProgramClauses<Interner>, 231 clauses: &chalk_ir::ProgramClauses<Interner>,
322 fmt: &mut fmt::Formatter<'_>, 232 fmt: &mut fmt::Formatter<'_>,
323 ) -> fmt::Result { 233 ) -> fmt::Result {
324 write!(fmt, "{:?}", clauses.as_slice(&Interner)) 234 write!(fmt, "{:?}", clauses.as_slice(&Interner))
325 } 235 }
326 pub fn debug_quantified_where_clauses( 236 pub(crate) fn debug_quantified_where_clauses(
327 &self, 237 &self,
328 clauses: &chalk_ir::QuantifiedWhereClauses<Interner>, 238 clauses: &chalk_ir::QuantifiedWhereClauses<Interner>,
329 fmt: &mut fmt::Formatter<'_>, 239 fmt: &mut fmt::Formatter<'_>,
@@ -339,7 +249,7 @@ mod unsafe_tls {
339 249
340 scoped_thread_local!(static PROGRAM: DebugContext); 250 scoped_thread_local!(static PROGRAM: DebugContext);
341 251
342 pub fn with_current_program<R>( 252 pub(crate) fn with_current_program<R>(
343 op: impl for<'a> FnOnce(Option<&'a DebugContext<'a>>) -> R, 253 op: impl for<'a> FnOnce(Option<&'a DebugContext<'a>>) -> R,
344 ) -> R { 254 ) -> R {
345 if PROGRAM.is_set() { 255 if PROGRAM.is_set() {
@@ -349,7 +259,7 @@ mod unsafe_tls {
349 } 259 }
350 } 260 }
351 261
352 pub fn set_current_program<OP, R>(p: &dyn HirDatabase, op: OP) -> R 262 pub(crate) fn set_current_program<OP, R>(p: &dyn HirDatabase, op: OP) -> R
353 where 263 where
354 OP: FnOnce() -> R, 264 OP: FnOnce() -> R,
355 { 265 {
diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs
index 0c950003e..02e17ba43 100644
--- a/crates/ide/src/diagnostics/fixes.rs
+++ b/crates/ide/src/diagnostics/fixes.rs
@@ -25,7 +25,7 @@ use crate::{diagnostics::Fix, references::rename::rename_with_semantics, FilePos
25/// A [Diagnostic] that potentially has a fix available. 25/// A [Diagnostic] that potentially has a fix available.
26/// 26///
27/// [Diagnostic]: hir::diagnostics::Diagnostic 27/// [Diagnostic]: hir::diagnostics::Diagnostic
28pub trait DiagnosticWithFix: Diagnostic { 28pub(crate) trait DiagnosticWithFix: Diagnostic {
29 fn fix(&self, sema: &Semantics<RootDatabase>) -> Option<Fix>; 29 fn fix(&self, sema: &Semantics<RootDatabase>) -> Option<Fix>;
30} 30}
31 31
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs
index 250f10f9f..10263537a 100644
--- a/crates/ide/src/doc_links.rs
+++ b/crates/ide/src/doc_links.rs
@@ -1,7 +1,6 @@
1//! Resolves and rewrites links in markdown documentation. 1//! Resolves and rewrites links in markdown documentation.
2 2
3use std::convert::TryFrom; 3use std::{convert::TryFrom, iter::once};
4use std::iter::once;
5 4
6use itertools::Itertools; 5use itertools::Itertools;
7use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag}; 6use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag};
@@ -21,10 +20,10 @@ use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset,
21 20
22use crate::{FilePosition, Semantics}; 21use crate::{FilePosition, Semantics};
23 22
24pub type DocumentationLink = String; 23pub(crate) type DocumentationLink = String;
25 24
26/// Rewrite documentation links in markdown to point to an online host (e.g. docs.rs) 25/// Rewrite documentation links in markdown to point to an online host (e.g. docs.rs)
27pub fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) -> String { 26pub(crate) fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) -> String {
28 let mut cb = |link: BrokenLink| { 27 let mut cb = |link: BrokenLink| {
29 Some(( 28 Some((
30 /*url*/ link.reference.to_owned().into(), 29 /*url*/ link.reference.to_owned().into(),
@@ -63,7 +62,7 @@ pub fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition)
63} 62}
64 63
65/// Remove all links in markdown documentation. 64/// Remove all links in markdown documentation.
66pub fn remove_links(markdown: &str) -> String { 65pub(crate) fn remove_links(markdown: &str) -> String {
67 let mut drop_link = false; 66 let mut drop_link = false;
68 67
69 let mut opts = Options::empty(); 68 let mut opts = Options::empty();
diff --git a/crates/ide/src/file_structure.rs b/crates/ide/src/file_structure.rs
index 6168fb837..415795e8c 100644
--- a/crates/ide/src/file_structure.rs
+++ b/crates/ide/src/file_structure.rs
@@ -27,7 +27,7 @@ pub struct StructureNode {
27// 27//
28// | VS Code | kbd:[Ctrl+Shift+O] 28// | VS Code | kbd:[Ctrl+Shift+O]
29// |=== 29// |===
30pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> { 30pub(crate) fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
31 let mut res = Vec::new(); 31 let mut res = Vec::new();
32 let mut stack = Vec::new(); 32 let mut stack = Vec::new();
33 33
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index b6113bda2..ac704ae21 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -1339,4 +1339,25 @@ fn main() {
1339"#, 1339"#,
1340 ); 1340 );
1341 } 1341 }
1342
1343 #[test]
1344 fn infer_call_method_return_associated_types_with_generic() {
1345 check(
1346 r#"
1347 pub trait Default {
1348 fn default() -> Self;
1349 }
1350 pub trait Foo {
1351 type Bar: Default;
1352 }
1353
1354 pub fn quux<T: Foo>() -> T::Bar {
1355 let y = Default::default();
1356 //^ <T as Foo>::Bar
1357
1358 y
1359 }
1360 "#,
1361 );
1362 }
1342} 1363}
diff --git a/crates/ide/src/join_lines.rs b/crates/ide/src/join_lines.rs
index e37702acd..b5a6f66fd 100644
--- a/crates/ide/src/join_lines.rs
+++ b/crates/ide/src/join_lines.rs
@@ -18,7 +18,7 @@ use text_edit::{TextEdit, TextEditBuilder};
18// 18//
19// | VS Code | **Rust Analyzer: Join lines** 19// | VS Code | **Rust Analyzer: Join lines**
20// |=== 20// |===
21pub fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit { 21pub(crate) fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit {
22 let range = if range.is_empty() { 22 let range = if range.is_empty() {
23 let syntax = file.syntax(); 23 let syntax = file.syntax();
24 let text = syntax.text().slice(range.start()..); 24 let text = syntax.text().slice(range.start()..);
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 4bc733b70..6288f7ea7 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -72,18 +72,20 @@ pub use crate::{
72 inlay_hints::{InlayHint, InlayHintsConfig, InlayKind}, 72 inlay_hints::{InlayHint, InlayHintsConfig, InlayKind},
73 markup::Markup, 73 markup::Markup,
74 prime_caches::PrimeCachesProgress, 74 prime_caches::PrimeCachesProgress,
75 references::{ 75 references::{rename::RenameError, Declaration, ReferenceSearchResult},
76 Declaration, Reference, ReferenceAccess, ReferenceKind, ReferenceSearchResult, RenameError,
77 },
78 runnables::{Runnable, RunnableKind, TestId}, 76 runnables::{Runnable, RunnableKind, TestId},
79 syntax_highlighting::{ 77 syntax_highlighting::{
80 Highlight, HighlightModifier, HighlightModifiers, HighlightTag, HighlightedRange, 78 tags::{Highlight, HighlightModifier, HighlightModifiers, HighlightTag},
79 HighlightedRange,
81 }, 80 },
82}; 81};
83pub use completion::{ 82pub use completion::{
84 CompletionConfig, CompletionItem, CompletionItemKind, CompletionScore, InsertTextFormat, 83 CompletionConfig, CompletionItem, CompletionItemKind, CompletionScore, InsertTextFormat,
85}; 84};
86pub use ide_db::call_info::CallInfo; 85pub use ide_db::{
86 call_info::CallInfo,
87 search::{Reference, ReferenceAccess, ReferenceKind},
88};
87 89
88pub use assists::{ 90pub use assists::{
89 utils::MergeBehaviour, Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist, 91 utils::MergeBehaviour, Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist,
@@ -503,7 +505,7 @@ impl Analysis {
503 position: FilePosition, 505 position: FilePosition,
504 new_name: &str, 506 new_name: &str,
505 ) -> Cancelable<Result<RangeInfo<SourceChange>, RenameError>> { 507 ) -> Cancelable<Result<RangeInfo<SourceChange>, RenameError>> {
506 self.with_db(|db| references::rename(db, position, new_name)) 508 self.with_db(|db| references::rename::rename(db, position, new_name))
507 } 509 }
508 510
509 pub fn structural_search_replace( 511 pub fn structural_search_replace(
diff --git a/crates/ide/src/markdown_remove.rs b/crates/ide/src/markdown_remove.rs
index 02ad39dfb..3ec5c629e 100644
--- a/crates/ide/src/markdown_remove.rs
+++ b/crates/ide/src/markdown_remove.rs
@@ -1,11 +1,10 @@
1//! Removes markdown from strings. 1//! Removes markdown from strings.
2
3use pulldown_cmark::{Event, Parser, Tag}; 2use pulldown_cmark::{Event, Parser, Tag};
4 3
5/// Removes all markdown, keeping the text and code blocks 4/// Removes all markdown, keeping the text and code blocks
6/// 5///
7/// Currently limited in styling, i.e. no ascii tables or lists 6/// Currently limited in styling, i.e. no ascii tables or lists
8pub fn remove_markdown(markdown: &str) -> String { 7pub(crate) fn remove_markdown(markdown: &str) -> String {
9 let mut out = String::new(); 8 let mut out = String::new();
10 let parser = Parser::new(markdown); 9 let parser = Parser::new(markdown);
11 10
diff --git a/crates/ide/src/matching_brace.rs b/crates/ide/src/matching_brace.rs
index cb6abb0db..d70248afe 100644
--- a/crates/ide/src/matching_brace.rs
+++ b/crates/ide/src/matching_brace.rs
@@ -15,7 +15,7 @@ use test_utils::mark;
15// 15//
16// | VS Code | **Rust Analyzer: Find matching brace** 16// | VS Code | **Rust Analyzer: Find matching brace**
17// |=== 17// |===
18pub fn matching_brace(file: &SourceFile, offset: TextSize) -> Option<TextSize> { 18pub(crate) fn matching_brace(file: &SourceFile, offset: TextSize) -> Option<TextSize> {
19 const BRACES: &[SyntaxKind] = 19 const BRACES: &[SyntaxKind] =
20 &[T!['{'], T!['}'], T!['['], T![']'], T!['('], T![')'], T![<], T![>], T![|], T![|]]; 20 &[T!['{'], T!['}'], T!['['], T![']'], T!['('], T![')'], T![<], T![>], T![|], T![|]];
21 let (brace_token, brace_idx) = file 21 let (brace_token, brace_idx) = file
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index a517081d5..e05465b32 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -14,7 +14,8 @@ pub(crate) mod rename;
14use hir::Semantics; 14use hir::Semantics;
15use ide_db::{ 15use ide_db::{
16 defs::{Definition, NameClass, NameRefClass}, 16 defs::{Definition, NameClass, NameRefClass},
17 search::SearchScope, 17 search::Reference,
18 search::{ReferenceAccess, ReferenceKind, SearchScope},
18 RootDatabase, 19 RootDatabase,
19}; 20};
20use syntax::{ 21use syntax::{
@@ -25,11 +26,6 @@ use syntax::{
25 26
26use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo}; 27use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo};
27 28
28pub(crate) use self::rename::rename;
29pub use self::rename::RenameError;
30
31pub use ide_db::search::{Reference, ReferenceAccess, ReferenceKind};
32
33#[derive(Debug, Clone)] 29#[derive(Debug, Clone)]
34pub struct ReferenceSearchResult { 30pub struct ReferenceSearchResult {
35 declaration: Declaration, 31 declaration: Declaration,
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index eb82456ad..2bd0e86e5 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -102,6 +102,7 @@ pub(crate) fn runnable(
102) -> Option<Runnable> { 102) -> Option<Runnable> {
103 match_ast! { 103 match_ast! {
104 match item { 104 match item {
105 ast::Struct(it) => runnable_struct(sema, it, file_id),
105 ast::Fn(it) => runnable_fn(sema, it, file_id), 106 ast::Fn(it) => runnable_fn(sema, it, file_id),
106 ast::Module(it) => runnable_mod(sema, it, file_id), 107 ast::Module(it) => runnable_mod(sema, it, file_id),
107 _ => None, 108 _ => None,
@@ -182,6 +183,43 @@ fn runnable_fn(
182 Some(Runnable { nav, kind, cfg }) 183 Some(Runnable { nav, kind, cfg })
183} 184}
184 185
186fn runnable_struct(
187 sema: &Semantics<RootDatabase>,
188 struct_def: ast::Struct,
189 file_id: FileId,
190) -> Option<Runnable> {
191 if !has_runnable_doc_test(&struct_def) {
192 return None;
193 }
194 let name_string = struct_def.name()?.text().to_string();
195
196 let attrs =
197 Attrs::from_attrs_owner(sema.db, InFile::new(HirFileId::from(file_id), &struct_def));
198 let cfg = attrs.cfg();
199
200 let test_id = match sema.to_def(&struct_def).map(|def| def.module(sema.db)) {
201 Some(module) => {
202 let path_iter = module
203 .path_to_root(sema.db)
204 .into_iter()
205 .rev()
206 .filter_map(|it| it.name(sema.db))
207 .map(|name| name.to_string());
208 let path = path_iter.chain(std::iter::once(name_string)).join("::");
209
210 TestId::Path(path)
211 }
212 None => TestId::Name(name_string),
213 };
214
215 let nav = NavigationTarget::from_doc_commented(
216 sema.db,
217 InFile::new(file_id.into(), &struct_def),
218 InFile::new(file_id.into(), &struct_def),
219 );
220 Some(Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg })
221}
222
185#[derive(Debug, Copy, Clone)] 223#[derive(Debug, Copy, Clone)]
186pub struct TestAttr { 224pub struct TestAttr {
187 pub ignore: bool, 225 pub ignore: bool,
@@ -215,8 +253,8 @@ const RUSTDOC_FENCE: &str = "```";
215const RUSTDOC_CODE_BLOCK_ATTRIBUTES_RUNNABLE: &[&str] = 253const RUSTDOC_CODE_BLOCK_ATTRIBUTES_RUNNABLE: &[&str] =
216 &["", "rust", "should_panic", "edition2015", "edition2018"]; 254 &["", "rust", "should_panic", "edition2015", "edition2018"];
217 255
218fn has_runnable_doc_test(fn_def: &ast::Fn) -> bool { 256fn has_runnable_doc_test(def: &dyn DocCommentsOwner) -> bool {
219 fn_def.doc_comment_text().map_or(false, |comments_text| { 257 def.doc_comment_text().map_or(false, |comments_text| {
220 let mut in_code_block = false; 258 let mut in_code_block = false;
221 259
222 for line in comments_text.lines() { 260 for line in comments_text.lines() {
@@ -487,8 +525,14 @@ fn should_have_no_runnable_5() {}
487/// let z = 55; 525/// let z = 55;
488/// ``` 526/// ```
489fn should_have_no_runnable_6() {} 527fn should_have_no_runnable_6() {}
528
529/// ```
530/// let x = 5;
531/// ```
532struct StructWithRunnable(String);
533
490"#, 534"#,
491 &[&BIN, &DOCTEST, &DOCTEST, &DOCTEST], 535 &[&BIN, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST],
492 expect![[r#" 536 expect![[r#"
493 [ 537 [
494 Runnable { 538 Runnable {
@@ -569,6 +613,26 @@ fn should_have_no_runnable_6() {}
569 }, 613 },
570 cfg: None, 614 cfg: None,
571 }, 615 },
616 Runnable {
617 nav: NavigationTarget {
618 file_id: FileId(
619 0,
620 ),
621 full_range: 756..821,
622 focus_range: None,
623 name: "StructWithRunnable",
624 kind: STRUCT,
625 container_name: None,
626 description: None,
627 docs: None,
628 },
629 kind: DocTest {
630 test_id: Path(
631 "StructWithRunnable",
632 ),
633 },
634 cfg: None,
635 },
572 ] 636 ]
573 "#]], 637 "#]],
574 ); 638 );
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index 624a63075..efcc8ecfe 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -2,7 +2,7 @@ mod format;
2mod html; 2mod html;
3mod injection; 3mod injection;
4mod macro_rules; 4mod macro_rules;
5mod tags; 5pub(crate) mod tags;
6#[cfg(test)] 6#[cfg(test)]
7mod tests; 7mod tests;
8 8
@@ -20,12 +20,13 @@ use syntax::{
20}; 20};
21 21
22use crate::{ 22use crate::{
23 syntax_highlighting::{format::FormatStringHighlighter, macro_rules::MacroRulesHighlighter}, 23 syntax_highlighting::{
24 FileId, 24 format::FormatStringHighlighter, macro_rules::MacroRulesHighlighter, tags::Highlight,
25 },
26 FileId, HighlightModifier, HighlightTag,
25}; 27};
26 28
27pub(crate) use html::highlight_as_html; 29pub(crate) use html::highlight_as_html;
28pub use tags::{Highlight, HighlightModifier, HighlightModifiers, HighlightTag};
29 30
30#[derive(Debug, Clone)] 31#[derive(Debug, Clone)]
31pub struct HighlightedRange { 32pub struct HighlightedRange {
diff --git a/crates/mbe/src/mbe_expander/matcher.rs b/crates/mbe/src/mbe_expander/matcher.rs
index b698b9832..39a8eefbd 100644
--- a/crates/mbe/src/mbe_expander/matcher.rs
+++ b/crates/mbe/src/mbe_expander/matcher.rs
@@ -61,16 +61,16 @@ macro_rules! err {
61 61
62#[derive(Debug, Default)] 62#[derive(Debug, Default)]
63pub(super) struct Match { 63pub(super) struct Match {
64 pub bindings: Bindings, 64 pub(super) bindings: Bindings,
65 /// We currently just keep the first error and count the rest to compare matches. 65 /// We currently just keep the first error and count the rest to compare matches.
66 pub err: Option<ExpandError>, 66 pub(super) err: Option<ExpandError>,
67 pub err_count: usize, 67 pub(super) err_count: usize,
68 /// How many top-level token trees were left to match. 68 /// How many top-level token trees were left to match.
69 pub unmatched_tts: usize, 69 pub(super) unmatched_tts: usize,
70} 70}
71 71
72impl Match { 72impl Match {
73 pub fn add_err(&mut self, err: ExpandError) { 73 pub(super) fn add_err(&mut self, err: ExpandError) {
74 let prev_err = self.err.take(); 74 let prev_err = self.err.take();
75 self.err = prev_err.or(Some(err)); 75 self.err = prev_err.or(Some(err));
76 self.err_count += 1; 76 self.err_count += 1;
diff --git a/crates/mbe/src/subtree_source.rs b/crates/mbe/src/subtree_source.rs
index 396ce8b16..ccc56c479 100644
--- a/crates/mbe/src/subtree_source.rs
+++ b/crates/mbe/src/subtree_source.rs
@@ -7,9 +7,9 @@ use tt::buffer::{Cursor, TokenBuffer};
7 7
8#[derive(Debug, Clone, Eq, PartialEq)] 8#[derive(Debug, Clone, Eq, PartialEq)]
9struct TtToken { 9struct TtToken {
10 pub kind: SyntaxKind, 10 kind: SyntaxKind,
11 pub is_joint_to_next: bool, 11 is_joint_to_next: bool,
12 pub text: SmolStr, 12 text: SmolStr,
13} 13}
14 14
15pub(crate) struct SubtreeTokenSource<'a> { 15pub(crate) struct SubtreeTokenSource<'a> {
@@ -21,7 +21,7 @@ pub(crate) struct SubtreeTokenSource<'a> {
21impl<'a> SubtreeTokenSource<'a> { 21impl<'a> SubtreeTokenSource<'a> {
22 // Helper function used in test 22 // Helper function used in test
23 #[cfg(test)] 23 #[cfg(test)]
24 pub fn text(&self) -> SmolStr { 24 pub(crate) fn text(&self) -> SmolStr {
25 match *self.get(self.curr.1) { 25 match *self.get(self.curr.1) {
26 Some(ref tt) => tt.text.clone(), 26 Some(ref tt) => tt.text.clone(),
27 _ => SmolStr::new(""), 27 _ => SmolStr::new(""),
@@ -30,7 +30,7 @@ impl<'a> SubtreeTokenSource<'a> {
30} 30}
31 31
32impl<'a> SubtreeTokenSource<'a> { 32impl<'a> SubtreeTokenSource<'a> {
33 pub fn new(buffer: &'a TokenBuffer) -> SubtreeTokenSource<'a> { 33 pub(crate) fn new(buffer: &'a TokenBuffer) -> SubtreeTokenSource<'a> {
34 let cursor = buffer.begin(); 34 let cursor = buffer.begin();
35 35
36 let mut res = SubtreeTokenSource { 36 let mut res = SubtreeTokenSource {
diff --git a/crates/proc_macro_api/src/process.rs b/crates/proc_macro_api/src/process.rs
index 51ffcaa78..907cb3db7 100644
--- a/crates/proc_macro_api/src/process.rs
+++ b/crates/proc_macro_api/src/process.rs
@@ -30,7 +30,7 @@ pub(crate) struct ProcMacroProcessThread {
30} 30}
31 31
32impl ProcMacroProcessSrv { 32impl ProcMacroProcessSrv {
33 pub fn run( 33 pub(crate) fn run(
34 process_path: PathBuf, 34 process_path: PathBuf,
35 args: impl IntoIterator<Item = impl AsRef<OsStr>>, 35 args: impl IntoIterator<Item = impl AsRef<OsStr>>,
36 ) -> io::Result<(ProcMacroProcessThread, ProcMacroProcessSrv)> { 36 ) -> io::Result<(ProcMacroProcessThread, ProcMacroProcessSrv)> {
@@ -48,7 +48,7 @@ impl ProcMacroProcessSrv {
48 Ok((thread, srv)) 48 Ok((thread, srv))
49 } 49 }
50 50
51 pub fn find_proc_macros( 51 pub(crate) fn find_proc_macros(
52 &self, 52 &self,
53 dylib_path: &Path, 53 dylib_path: &Path,
54 ) -> Result<Vec<(String, ProcMacroKind)>, tt::ExpansionError> { 54 ) -> Result<Vec<(String, ProcMacroKind)>, tt::ExpansionError> {
@@ -58,7 +58,7 @@ impl ProcMacroProcessSrv {
58 Ok(result.macros) 58 Ok(result.macros)
59 } 59 }
60 60
61 pub fn custom_derive( 61 pub(crate) fn custom_derive(
62 &self, 62 &self,
63 dylib_path: &Path, 63 dylib_path: &Path,
64 subtree: &Subtree, 64 subtree: &Subtree,
@@ -75,7 +75,7 @@ impl ProcMacroProcessSrv {
75 Ok(result.expansion) 75 Ok(result.expansion)
76 } 76 }
77 77
78 pub fn send_task<R>(&self, req: Request) -> Result<R, tt::ExpansionError> 78 pub(crate) fn send_task<R>(&self, req: Request) -> Result<R, tt::ExpansionError>
79 where 79 where
80 R: TryFrom<Response, Error = &'static str>, 80 R: TryFrom<Response, Error = &'static str>,
81 { 81 {
diff --git a/crates/proc_macro_api/src/rpc.rs b/crates/proc_macro_api/src/rpc.rs
index 47624163e..203109ca4 100644
--- a/crates/proc_macro_api/src/rpc.rs
+++ b/crates/proc_macro_api/src/rpc.rs
@@ -75,18 +75,18 @@ struct TokenIdDef(u32);
75#[serde(remote = "Delimiter")] 75#[serde(remote = "Delimiter")]
76struct DelimiterDef { 76struct DelimiterDef {
77 #[serde(with = "TokenIdDef")] 77 #[serde(with = "TokenIdDef")]
78 pub id: TokenId, 78 id: TokenId,
79 #[serde(with = "DelimiterKindDef")] 79 #[serde(with = "DelimiterKindDef")]
80 pub kind: DelimiterKind, 80 kind: DelimiterKind,
81} 81}
82 82
83#[derive(Serialize, Deserialize)] 83#[derive(Serialize, Deserialize)]
84#[serde(remote = "Subtree")] 84#[serde(remote = "Subtree")]
85struct SubtreeDef { 85struct SubtreeDef {
86 #[serde(default, with = "opt_delimiter_def")] 86 #[serde(default, with = "opt_delimiter_def")]
87 pub delimiter: Option<Delimiter>, 87 delimiter: Option<Delimiter>,
88 #[serde(with = "vec_token_tree")] 88 #[serde(with = "vec_token_tree")]
89 pub token_trees: Vec<TokenTree>, 89 token_trees: Vec<TokenTree>,
90} 90}
91 91
92#[derive(Serialize, Deserialize)] 92#[derive(Serialize, Deserialize)]
@@ -112,19 +112,19 @@ enum LeafDef {
112#[derive(Serialize, Deserialize)] 112#[derive(Serialize, Deserialize)]
113#[serde(remote = "Literal")] 113#[serde(remote = "Literal")]
114struct LiteralDef { 114struct LiteralDef {
115 pub text: SmolStr, 115 text: SmolStr,
116 #[serde(with = "TokenIdDef")] 116 #[serde(with = "TokenIdDef")]
117 pub id: TokenId, 117 id: TokenId,
118} 118}
119 119
120#[derive(Serialize, Deserialize)] 120#[derive(Serialize, Deserialize)]
121#[serde(remote = "Punct")] 121#[serde(remote = "Punct")]
122struct PunctDef { 122struct PunctDef {
123 pub char: char, 123 char: char,
124 #[serde(with = "SpacingDef")] 124 #[serde(with = "SpacingDef")]
125 pub spacing: Spacing, 125 spacing: Spacing,
126 #[serde(with = "TokenIdDef")] 126 #[serde(with = "TokenIdDef")]
127 pub id: TokenId, 127 id: TokenId,
128} 128}
129 129
130#[derive(Serialize, Deserialize)] 130#[derive(Serialize, Deserialize)]
@@ -137,16 +137,16 @@ enum SpacingDef {
137#[derive(Serialize, Deserialize)] 137#[derive(Serialize, Deserialize)]
138#[serde(remote = "Ident")] 138#[serde(remote = "Ident")]
139struct IdentDef { 139struct IdentDef {
140 pub text: SmolStr, 140 text: SmolStr,
141 #[serde(with = "TokenIdDef")] 141 #[serde(with = "TokenIdDef")]
142 pub id: TokenId, 142 id: TokenId,
143} 143}
144 144
145mod opt_delimiter_def { 145mod opt_delimiter_def {
146 use super::{Delimiter, DelimiterDef}; 146 use super::{Delimiter, DelimiterDef};
147 use serde::{Deserialize, Deserializer, Serialize, Serializer}; 147 use serde::{Deserialize, Deserializer, Serialize, Serializer};
148 148
149 pub fn serialize<S>(value: &Option<Delimiter>, serializer: S) -> Result<S::Ok, S::Error> 149 pub(super) fn serialize<S>(value: &Option<Delimiter>, serializer: S) -> Result<S::Ok, S::Error>
150 where 150 where
151 S: Serializer, 151 S: Serializer,
152 { 152 {
@@ -155,7 +155,7 @@ mod opt_delimiter_def {
155 value.as_ref().map(Helper).serialize(serializer) 155 value.as_ref().map(Helper).serialize(serializer)
156 } 156 }
157 157
158 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Delimiter>, D::Error> 158 pub(super) fn deserialize<'de, D>(deserializer: D) -> Result<Option<Delimiter>, D::Error>
159 where 159 where
160 D: Deserializer<'de>, 160 D: Deserializer<'de>,
161 { 161 {
@@ -170,7 +170,7 @@ mod opt_subtree_def {
170 use super::{Subtree, SubtreeDef}; 170 use super::{Subtree, SubtreeDef};
171 use serde::{Deserialize, Deserializer, Serialize, Serializer}; 171 use serde::{Deserialize, Deserializer, Serialize, Serializer};
172 172
173 pub fn serialize<S>(value: &Option<Subtree>, serializer: S) -> Result<S::Ok, S::Error> 173 pub(super) fn serialize<S>(value: &Option<Subtree>, serializer: S) -> Result<S::Ok, S::Error>
174 where 174 where
175 S: Serializer, 175 S: Serializer,
176 { 176 {
@@ -179,7 +179,7 @@ mod opt_subtree_def {
179 value.as_ref().map(Helper).serialize(serializer) 179 value.as_ref().map(Helper).serialize(serializer)
180 } 180 }
181 181
182 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Subtree>, D::Error> 182 pub(super) fn deserialize<'de, D>(deserializer: D) -> Result<Option<Subtree>, D::Error>
183 where 183 where
184 D: Deserializer<'de>, 184 D: Deserializer<'de>,
185 { 185 {
@@ -194,7 +194,7 @@ mod vec_token_tree {
194 use super::{TokenTree, TokenTreeDef}; 194 use super::{TokenTree, TokenTreeDef};
195 use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer}; 195 use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer};
196 196
197 pub fn serialize<S>(value: &Vec<TokenTree>, serializer: S) -> Result<S::Ok, S::Error> 197 pub(super) fn serialize<S>(value: &Vec<TokenTree>, serializer: S) -> Result<S::Ok, S::Error>
198 where 198 where
199 S: Serializer, 199 S: Serializer,
200 { 200 {
@@ -209,7 +209,7 @@ mod vec_token_tree {
209 seq.end() 209 seq.end()
210 } 210 }
211 211
212 pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<TokenTree>, D::Error> 212 pub(super) fn deserialize<'de, D>(deserializer: D) -> Result<Vec<TokenTree>, D::Error>
213 where 213 where
214 D: Deserializer<'de>, 214 D: Deserializer<'de>,
215 { 215 {
diff --git a/crates/proc_macro_srv/src/lib.rs b/crates/proc_macro_srv/src/lib.rs
index 7e4e4ad50..6e890f8e2 100644
--- a/crates/proc_macro_srv/src/lib.rs
+++ b/crates/proc_macro_srv/src/lib.rs
@@ -9,6 +9,7 @@
9//! RA than `proc-macro2` token stream. 9//! RA than `proc-macro2` token stream.
10//! * By **copying** the whole rustc `lib_proc_macro` code, we are able to build this with `stable` 10//! * By **copying** the whole rustc `lib_proc_macro` code, we are able to build this with `stable`
11//! rustc rather than `unstable`. (Although in general ABI compatibility is still an issue)… 11//! rustc rather than `unstable`. (Although in general ABI compatibility is still an issue)…
12#![allow(unreachable_pub)]
12 13
13#[allow(dead_code)] 14#[allow(dead_code)]
14#[doc(hidden)] 15#[doc(hidden)]
diff --git a/crates/profile/src/hprof.rs b/crates/profile/src/hprof.rs
index 934cc8e37..8957ea016 100644
--- a/crates/profile/src/hprof.rs
+++ b/crates/profile/src/hprof.rs
@@ -27,7 +27,7 @@ pub fn init_from(spec: &str) {
27 filter.install(); 27 filter.install();
28} 28}
29 29
30pub type Label = &'static str; 30type Label = &'static str;
31 31
32/// This function starts a profiling scope in the current execution stack with a given description. 32/// This function starts a profiling scope in the current execution stack with a given description.
33/// It returns a `Profile` struct that measures elapsed time between this method invocation and `Profile` struct drop. 33/// It returns a `Profile` struct that measures elapsed time between this method invocation and `Profile` struct drop.
@@ -173,7 +173,7 @@ impl ProfileStack {
173 true 173 true
174 } 174 }
175 175
176 pub fn pop(&mut self, label: Label, detail: Option<String>) { 176 fn pop(&mut self, label: Label, detail: Option<String>) {
177 let start = self.starts.pop().unwrap(); 177 let start = self.starts.pop().unwrap();
178 let duration = start.elapsed(); 178 let duration = start.elapsed();
179 self.messages.finish(Message { duration, label, detail }); 179 self.messages.finish(Message { duration, label, detail });
diff --git a/crates/profile/src/tree.rs b/crates/profile/src/tree.rs
index 096f58511..3fac1f36c 100644
--- a/crates/profile/src/tree.rs
+++ b/crates/profile/src/tree.rs
@@ -4,15 +4,15 @@ use std::ops;
4use arena::Arena; 4use arena::Arena;
5 5
6#[derive(Default)] 6#[derive(Default)]
7pub struct Tree<T> { 7pub(crate) struct Tree<T> {
8 nodes: Arena<Node<T>>, 8 nodes: Arena<Node<T>>,
9 current_path: Vec<(Idx<T>, Option<Idx<T>>)>, 9 current_path: Vec<(Idx<T>, Option<Idx<T>>)>,
10} 10}
11 11
12pub type Idx<T> = arena::Idx<Node<T>>; 12pub(crate) type Idx<T> = arena::Idx<Node<T>>;
13 13
14impl<T> Tree<T> { 14impl<T> Tree<T> {
15 pub fn start(&mut self) 15 pub(crate) fn start(&mut self)
16 where 16 where
17 T: Default, 17 T: Default,
18 { 18 {
@@ -30,19 +30,19 @@ impl<T> Tree<T> {
30 self.current_path.push((me, None)); 30 self.current_path.push((me, None));
31 } 31 }
32 32
33 pub fn finish(&mut self, data: T) { 33 pub(crate) fn finish(&mut self, data: T) {
34 let (me, _last_child) = self.current_path.pop().unwrap(); 34 let (me, _last_child) = self.current_path.pop().unwrap();
35 self.nodes[me].data = data; 35 self.nodes[me].data = data;
36 } 36 }
37 37
38 pub fn root(&self) -> Option<Idx<T>> { 38 pub(crate) fn root(&self) -> Option<Idx<T>> {
39 self.nodes.iter().next().map(|(idx, _)| idx) 39 self.nodes.iter().next().map(|(idx, _)| idx)
40 } 40 }
41 41
42 pub fn children(&self, idx: Idx<T>) -> impl Iterator<Item = Idx<T>> + '_ { 42 pub(crate) fn children(&self, idx: Idx<T>) -> impl Iterator<Item = Idx<T>> + '_ {
43 NodeIter { nodes: &self.nodes, next: self.nodes[idx].first_child } 43 NodeIter { nodes: &self.nodes, next: self.nodes[idx].first_child }
44 } 44 }
45 pub fn clear(&mut self) { 45 pub(crate) fn clear(&mut self) {
46 self.nodes.clear(); 46 self.nodes.clear();
47 self.current_path.clear(); 47 self.current_path.clear();
48 } 48 }
@@ -55,7 +55,7 @@ impl<T> ops::Index<Idx<T>> for Tree<T> {
55 } 55 }
56} 56}
57 57
58pub struct Node<T> { 58pub(crate) struct Node<T> {
59 data: T, 59 data: T,
60 first_child: Option<Idx<T>>, 60 first_child: Option<Idx<T>>,
61 next_sibling: Option<Idx<T>>, 61 next_sibling: Option<Idx<T>>,
diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs
index e5c2d2b25..d5f6a4025 100644
--- a/crates/project_model/src/cargo_workspace.rs
+++ b/crates/project_model/src/cargo_workspace.rs
@@ -278,13 +278,13 @@ impl CargoWorkspace {
278} 278}
279 279
280#[derive(Debug, Clone, Default)] 280#[derive(Debug, Clone, Default)]
281pub struct ExternResources { 281pub(crate) struct ExternResources {
282 out_dirs: FxHashMap<PackageId, AbsPathBuf>, 282 out_dirs: FxHashMap<PackageId, AbsPathBuf>,
283 proc_dylib_paths: FxHashMap<PackageId, AbsPathBuf>, 283 proc_dylib_paths: FxHashMap<PackageId, AbsPathBuf>,
284 cfgs: FxHashMap<PackageId, Vec<CfgFlag>>, 284 cfgs: FxHashMap<PackageId, Vec<CfgFlag>>,
285} 285}
286 286
287pub fn load_extern_resources( 287pub(crate) fn load_extern_resources(
288 cargo_toml: &Path, 288 cargo_toml: &Path,
289 cargo_features: &CargoConfig, 289 cargo_features: &CargoConfig,
290) -> Result<ExternResources> { 290) -> Result<ExternResources> {
diff --git a/crates/project_model/src/sysroot.rs b/crates/project_model/src/sysroot.rs
index b2ff98a15..3fe494729 100644
--- a/crates/project_model/src/sysroot.rs
+++ b/crates/project_model/src/sysroot.rs
@@ -17,7 +17,7 @@ pub struct Sysroot {
17 crates: Arena<SysrootCrateData>, 17 crates: Arena<SysrootCrateData>,
18} 18}
19 19
20pub type SysrootCrate = Idx<SysrootCrateData>; 20pub(crate) type SysrootCrate = Idx<SysrootCrateData>;
21 21
22#[derive(Debug, Clone, Eq, PartialEq)] 22#[derive(Debug, Clone, Eq, PartialEq)]
23pub struct SysrootCrateData { 23pub struct SysrootCrateData {
@@ -60,9 +60,7 @@ impl Sysroot {
60 let mut sysroot = Sysroot { crates: Arena::default() }; 60 let mut sysroot = Sysroot { crates: Arena::default() };
61 61
62 for name in SYSROOT_CRATES.trim().lines() { 62 for name in SYSROOT_CRATES.trim().lines() {
63 // FIXME: first path when 1.47 comes out 63 let root = [format!("{}/src/lib.rs", name), format!("lib{}/lib.rs", name)]
64 // https://github.com/rust-lang/rust/pull/73265
65 let root = [format!("lib{}/lib.rs", name), format!("{}/src/lib.rs", name)]
66 .iter() 64 .iter()
67 .map(|it| sysroot_src_dir.join(it)) 65 .map(|it| sysroot_src_dir.join(it))
68 .find(|it| it.exists()); 66 .find(|it| it.exists());
@@ -149,9 +147,6 @@ try running `rustup component add rust-src` or set `RUST_SRC_PATH`",
149 147
150fn get_rust_src(sysroot_path: &AbsPath) -> Option<AbsPathBuf> { 148fn get_rust_src(sysroot_path: &AbsPath) -> Option<AbsPathBuf> {
151 // Try the new path first since the old one still exists. 149 // Try the new path first since the old one still exists.
152 //
153 // FIXME: remove `src` when 1.47 comes out
154 // https://github.com/rust-lang/rust/pull/73265
155 let rust_src = sysroot_path.join("lib/rustlib/src/rust"); 150 let rust_src = sysroot_path.join("lib/rustlib/src/rust");
156 log::debug!("Checking sysroot (looking for `library` and `src` dirs): {}", rust_src.display()); 151 log::debug!("Checking sysroot (looking for `library` and `src` dirs): {}", rust_src.display());
157 ["library", "src"].iter().map(|it| rust_src.join(it)).find(|it| it.exists()) 152 ["library", "src"].iter().map(|it| rust_src.join(it)).find(|it| it.exists())
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index 4175e569e..21fba8302 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -81,7 +81,7 @@ mod tracing_setup {
81 use tracing_subscriber::Registry; 81 use tracing_subscriber::Registry;
82 use tracing_tree::HierarchicalLayer; 82 use tracing_tree::HierarchicalLayer;
83 83
84 pub fn setup_tracing() -> super::Result<()> { 84 pub(crate) fn setup_tracing() -> super::Result<()> {
85 let filter = EnvFilter::from_env("CHALK_DEBUG"); 85 let filter = EnvFilter::from_env("CHALK_DEBUG");
86 let layer = HierarchicalLayer::default() 86 let layer = HierarchicalLayer::default()
87 .with_indent_lines(true) 87 .with_indent_lines(true)
diff --git a/crates/rust-analyzer/src/cli/progress_report.rs b/crates/rust-analyzer/src/cli/progress_report.rs
index 31867a1e9..bdbe565e6 100644
--- a/crates/rust-analyzer/src/cli/progress_report.rs
+++ b/crates/rust-analyzer/src/cli/progress_report.rs
@@ -4,7 +4,7 @@
4use std::io::Write; 4use std::io::Write;
5 5
6/// A Simple ASCII Progress Bar 6/// A Simple ASCII Progress Bar
7pub struct ProgressReport { 7pub(crate) struct ProgressReport {
8 curr: f32, 8 curr: f32,
9 text: String, 9 text: String,
10 hidden: bool, 10 hidden: bool,
@@ -15,7 +15,7 @@ pub struct ProgressReport {
15} 15}
16 16
17impl ProgressReport { 17impl ProgressReport {
18 pub fn new(len: u64) -> ProgressReport { 18 pub(crate) fn new(len: u64) -> ProgressReport {
19 ProgressReport { 19 ProgressReport {
20 curr: 0.0, 20 curr: 0.0,
21 text: String::new(), 21 text: String::new(),
@@ -26,7 +26,7 @@ impl ProgressReport {
26 } 26 }
27 } 27 }
28 28
29 pub fn hidden() -> ProgressReport { 29 pub(crate) fn hidden() -> ProgressReport {
30 ProgressReport { 30 ProgressReport {
31 curr: 0.0, 31 curr: 0.0,
32 text: String::new(), 32 text: String::new(),
@@ -37,18 +37,18 @@ impl ProgressReport {
37 } 37 }
38 } 38 }
39 39
40 pub fn set_message(&mut self, msg: &str) { 40 pub(crate) fn set_message(&mut self, msg: &str) {
41 self.msg = msg.to_string(); 41 self.msg = msg.to_string();
42 self.tick(); 42 self.tick();
43 } 43 }
44 44
45 pub fn println<I: Into<String>>(&mut self, msg: I) { 45 pub(crate) fn println<I: Into<String>>(&mut self, msg: I) {
46 self.clear(); 46 self.clear();
47 println!("{}", msg.into()); 47 println!("{}", msg.into());
48 self.tick(); 48 self.tick();
49 } 49 }
50 50
51 pub fn inc(&mut self, delta: u64) { 51 pub(crate) fn inc(&mut self, delta: u64) {
52 self.pos += delta; 52 self.pos += delta;
53 if self.len == 0 { 53 if self.len == 0 {
54 self.set_value(0.0) 54 self.set_value(0.0)
@@ -58,11 +58,11 @@ impl ProgressReport {
58 self.tick(); 58 self.tick();
59 } 59 }
60 60
61 pub fn finish_and_clear(&mut self) { 61 pub(crate) fn finish_and_clear(&mut self) {
62 self.clear(); 62 self.clear();
63 } 63 }
64 64
65 pub fn tick(&mut self) { 65 pub(crate) fn tick(&mut self) {
66 if self.hidden { 66 if self.hidden {
67 return; 67 return;
68 } 68 }
diff --git a/crates/rust-analyzer/src/dispatch.rs b/crates/rust-analyzer/src/dispatch.rs
index 7a87515e9..81b85a269 100644
--- a/crates/rust-analyzer/src/dispatch.rs
+++ b/crates/rust-analyzer/src/dispatch.rs
@@ -28,17 +28,16 @@ impl<'a> RequestDispatcher<'a> {
28 { 28 {
29 let (id, params) = match self.parse::<R>() { 29 let (id, params) = match self.parse::<R>() {
30 Some(it) => it, 30 Some(it) => it,
31 None => { 31 None => return Ok(self),
32 return Ok(self);
33 }
34 }; 32 };
35 let world = panic::AssertUnwindSafe(&mut *self.global_state); 33 let world = panic::AssertUnwindSafe(&mut *self.global_state);
34
36 let response = panic::catch_unwind(move || { 35 let response = panic::catch_unwind(move || {
37 let _pctx = stdx::panic_context::enter(format!("request: {} {:#?}", R::METHOD, params)); 36 let _pctx = stdx::panic_context::enter(format!("request: {} {:#?}", R::METHOD, params));
38 let result = f(world.0, params); 37 let result = f(world.0, params);
39 result_to_response::<R>(id, result) 38 result_to_response::<R>(id, result)
40 }) 39 })
41 .map_err(|_| format!("sync task {:?} panicked", R::METHOD))?; 40 .map_err(|_err| format!("sync task {:?} panicked", R::METHOD))?;
42 self.global_state.respond(response); 41 self.global_state.respond(response);
43 Ok(self) 42 Ok(self)
44 } 43 }
@@ -47,7 +46,7 @@ impl<'a> RequestDispatcher<'a> {
47 pub(crate) fn on<R>( 46 pub(crate) fn on<R>(
48 &mut self, 47 &mut self,
49 f: fn(GlobalStateSnapshot, R::Params) -> Result<R::Result>, 48 f: fn(GlobalStateSnapshot, R::Params) -> Result<R::Result>,
50 ) -> Result<&mut Self> 49 ) -> &mut Self
51 where 50 where
52 R: lsp_types::request::Request + 'static, 51 R: lsp_types::request::Request + 'static,
53 R::Params: DeserializeOwned + Send + fmt::Debug + 'static, 52 R::Params: DeserializeOwned + Send + fmt::Debug + 'static,
@@ -55,9 +54,7 @@ impl<'a> RequestDispatcher<'a> {
55 { 54 {
56 let (id, params) = match self.parse::<R>() { 55 let (id, params) = match self.parse::<R>() {
57 Some(it) => it, 56 Some(it) => it,
58 None => { 57 None => return self,
59 return Ok(self);
60 }
61 }; 58 };
62 59
63 self.global_state.task_pool.handle.spawn({ 60 self.global_state.task_pool.handle.spawn({
@@ -71,7 +68,7 @@ impl<'a> RequestDispatcher<'a> {
71 } 68 }
72 }); 69 });
73 70
74 Ok(self) 71 self
75 } 72 }
76 73
77 pub(crate) fn finish(&mut self) { 74 pub(crate) fn finish(&mut self) {
@@ -82,7 +79,7 @@ impl<'a> RequestDispatcher<'a> {
82 lsp_server::ErrorCode::MethodNotFound as i32, 79 lsp_server::ErrorCode::MethodNotFound as i32,
83 "unknown request".to_string(), 80 "unknown request".to_string(),
84 ); 81 );
85 self.global_state.respond(response) 82 self.global_state.respond(response);
86 } 83 }
87 } 84 }
88 85
@@ -91,15 +88,24 @@ impl<'a> RequestDispatcher<'a> {
91 R: lsp_types::request::Request + 'static, 88 R: lsp_types::request::Request + 'static,
92 R::Params: DeserializeOwned + 'static, 89 R::Params: DeserializeOwned + 'static,
93 { 90 {
94 let req = self.req.take()?; 91 let req = match &self.req {
95 let (id, params) = match req.extract::<R::Params>(R::METHOD) { 92 Some(req) if req.method == R::METHOD => self.req.take().unwrap(),
96 Ok(it) => it, 93 _ => return None,
97 Err(req) => { 94 };
98 self.req = Some(req); 95
96 let res = crate::from_json(R::METHOD, req.params);
97 match res {
98 Ok(params) => return Some((req.id, params)),
99 Err(err) => {
100 let response = lsp_server::Response::new_err(
101 req.id,
102 lsp_server::ErrorCode::InvalidParams as i32,
103 err.to_string(),
104 );
105 self.global_state.respond(response);
99 return None; 106 return None;
100 } 107 }
101 }; 108 }
102 Some((id, params))
103 } 109 }
104} 110}
105 111
diff --git a/crates/rust-analyzer/src/document.rs b/crates/rust-analyzer/src/document.rs
index e882c9865..04c7ee150 100644
--- a/crates/rust-analyzer/src/document.rs
+++ b/crates/rust-analyzer/src/document.rs
@@ -6,11 +6,11 @@
6/// client notifications. 6/// client notifications.
7#[derive(Debug, Clone)] 7#[derive(Debug, Clone)]
8pub(crate) struct DocumentData { 8pub(crate) struct DocumentData {
9 pub version: Option<i64>, 9 pub(crate) version: Option<i64>,
10} 10}
11 11
12impl DocumentData { 12impl DocumentData {
13 pub fn new(version: i64) -> Self { 13 pub(crate) fn new(version: i64) -> Self {
14 DocumentData { version: Some(version) } 14 DocumentData { version: Some(version) }
15 } 15 }
16} 16}
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index 673a2eebc..63c70a09d 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -87,7 +87,7 @@ pub(crate) struct GlobalStateSnapshot {
87 pub(crate) check_fixes: CheckFixes, 87 pub(crate) check_fixes: CheckFixes,
88 pub(crate) latest_requests: Arc<RwLock<LatestRequests>>, 88 pub(crate) latest_requests: Arc<RwLock<LatestRequests>>,
89 mem_docs: FxHashMap<VfsPath, DocumentData>, 89 mem_docs: FxHashMap<VfsPath, DocumentData>,
90 pub semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>, 90 pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>,
91 vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>, 91 vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>,
92 pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>, 92 pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
93} 93}
diff --git a/crates/rust-analyzer/src/lib.rs b/crates/rust-analyzer/src/lib.rs
index 87f72b497..ad08f1afb 100644
--- a/crates/rust-analyzer/src/lib.rs
+++ b/crates/rust-analyzer/src/lib.rs
@@ -37,14 +37,16 @@ mod document;
37pub mod lsp_ext; 37pub mod lsp_ext;
38pub mod config; 38pub mod config;
39 39
40use serde::de::DeserializeOwned;
41
42pub type Result<T, E = Box<dyn std::error::Error + Send + Sync>> = std::result::Result<T, E>;
43pub use crate::{caps::server_capabilities, main_loop::main_loop};
44use ide::AnalysisHost; 40use ide::AnalysisHost;
41use serde::de::DeserializeOwned;
45use std::fmt; 42use std::fmt;
46use vfs::Vfs; 43use vfs::Vfs;
47 44
45pub use crate::{caps::server_capabilities, main_loop::main_loop};
46
47pub type Error = Box<dyn std::error::Error + Send + Sync>;
48pub type Result<T, E = Error> = std::result::Result<T, E>;
49
48pub fn from_json<T: DeserializeOwned>(what: &'static str, json: serde_json::Value) -> Result<T> { 50pub fn from_json<T: DeserializeOwned>(what: &'static str, json: serde_json::Value) -> Result<T> {
49 let res = T::deserialize(&json) 51 let res = T::deserialize(&json)
50 .map_err(|e| format!("Failed to deserialize {}: {}; {}", what, e, json))?; 52 .map_err(|e| format!("Failed to deserialize {}: {}; {}", what, e, json))?;
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index ff855fe1a..e9d08ff15 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -190,15 +190,35 @@ impl GlobalState {
190 } 190 }
191 lsp_server::Message::Response(resp) => self.complete_request(resp), 191 lsp_server::Message::Response(resp) => self.complete_request(resp),
192 }, 192 },
193 Event::Task(task) => match task { 193 Event::Task(mut task) => {
194 Task::Response(response) => self.respond(response), 194 let _p = profile::span("GlobalState::handle_event/task");
195 Task::Diagnostics(diagnostics_per_file) => { 195 let mut prime_caches_started = false;
196 for (file_id, diagnostics) in diagnostics_per_file { 196 let mut prime_caches_progress = None;
197 self.diagnostics.set_native_diagnostics(file_id, diagnostics) 197 loop {
198 match task {
199 Task::Response(response) => self.respond(response),
200 Task::Diagnostics(diagnostics_per_file) => {
201 for (file_id, diagnostics) in diagnostics_per_file {
202 self.diagnostics.set_native_diagnostics(file_id, diagnostics)
203 }
204 }
205 Task::Workspaces(workspaces) => self.switch_workspaces(workspaces),
206 Task::PrimeCaches(progress) => {
207 if let PrimeCachesProgress::Started = progress {
208 prime_caches_started = true;
209 }
210
211 prime_caches_progress = Some(progress);
212 }
198 } 213 }
214 // Coalesce multiple task events into one loop turn
215 task = match self.task_pool.receiver.try_recv() {
216 Ok(task) => task,
217 Err(_) => break,
218 };
199 } 219 }
200 Task::Workspaces(workspaces) => self.switch_workspaces(workspaces), 220
201 Task::PrimeCaches(progress) => { 221 if let Some(progress) = prime_caches_progress {
202 let (state, message, fraction); 222 let (state, message, fraction);
203 match progress { 223 match progress {
204 PrimeCachesProgress::Started => { 224 PrimeCachesProgress::Started => {
@@ -218,9 +238,14 @@ impl GlobalState {
218 } 238 }
219 }; 239 };
220 240
241 if state != Progress::Begin && prime_caches_started {
242 // Progress indicator needs to be created first.
243 self.report_progress("indexing", Progress::Begin, None, Some(0.0));
244 }
245
221 self.report_progress("indexing", state, message, Some(fraction)); 246 self.report_progress("indexing", state, message, Some(fraction));
222 } 247 }
223 }, 248 }
224 Event::Vfs(mut task) => { 249 Event::Vfs(mut task) => {
225 let _p = profile::span("GlobalState::handle_event/vfs"); 250 let _p = profile::span("GlobalState::handle_event/vfs");
226 loop { 251 loop {
@@ -403,53 +428,49 @@ impl GlobalState {
403 handlers::handle_matching_brace(s.snapshot(), p) 428 handlers::handle_matching_brace(s.snapshot(), p)
404 })? 429 })?
405 .on_sync::<lsp_ext::MemoryUsage>(|s, p| handlers::handle_memory_usage(s, p))? 430 .on_sync::<lsp_ext::MemoryUsage>(|s, p| handlers::handle_memory_usage(s, p))?
406 .on::<lsp_ext::AnalyzerStatus>(handlers::handle_analyzer_status)? 431 .on::<lsp_ext::AnalyzerStatus>(handlers::handle_analyzer_status)
407 .on::<lsp_ext::SyntaxTree>(handlers::handle_syntax_tree)? 432 .on::<lsp_ext::SyntaxTree>(handlers::handle_syntax_tree)
408 .on::<lsp_ext::ExpandMacro>(handlers::handle_expand_macro)? 433 .on::<lsp_ext::ExpandMacro>(handlers::handle_expand_macro)
409 .on::<lsp_ext::ParentModule>(handlers::handle_parent_module)? 434 .on::<lsp_ext::ParentModule>(handlers::handle_parent_module)
410 .on::<lsp_ext::Runnables>(handlers::handle_runnables)? 435 .on::<lsp_ext::Runnables>(handlers::handle_runnables)
411 .on::<lsp_ext::InlayHints>(handlers::handle_inlay_hints)? 436 .on::<lsp_ext::InlayHints>(handlers::handle_inlay_hints)
412 .on::<lsp_ext::CodeActionRequest>(handlers::handle_code_action)? 437 .on::<lsp_ext::CodeActionRequest>(handlers::handle_code_action)
413 .on::<lsp_ext::ResolveCodeActionRequest>(handlers::handle_resolve_code_action)? 438 .on::<lsp_ext::ResolveCodeActionRequest>(handlers::handle_resolve_code_action)
414 .on::<lsp_ext::HoverRequest>(handlers::handle_hover)? 439 .on::<lsp_ext::HoverRequest>(handlers::handle_hover)
415 .on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs)? 440 .on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs)
416 .on::<lsp_types::request::OnTypeFormatting>(handlers::handle_on_type_formatting)? 441 .on::<lsp_types::request::OnTypeFormatting>(handlers::handle_on_type_formatting)
417 .on::<lsp_types::request::DocumentSymbolRequest>(handlers::handle_document_symbol)? 442 .on::<lsp_types::request::DocumentSymbolRequest>(handlers::handle_document_symbol)
418 .on::<lsp_types::request::WorkspaceSymbol>(handlers::handle_workspace_symbol)? 443 .on::<lsp_types::request::WorkspaceSymbol>(handlers::handle_workspace_symbol)
419 .on::<lsp_types::request::GotoDefinition>(handlers::handle_goto_definition)? 444 .on::<lsp_types::request::GotoDefinition>(handlers::handle_goto_definition)
420 .on::<lsp_types::request::GotoImplementation>(handlers::handle_goto_implementation)? 445 .on::<lsp_types::request::GotoImplementation>(handlers::handle_goto_implementation)
421 .on::<lsp_types::request::GotoTypeDefinition>(handlers::handle_goto_type_definition)? 446 .on::<lsp_types::request::GotoTypeDefinition>(handlers::handle_goto_type_definition)
422 .on::<lsp_types::request::Completion>(handlers::handle_completion)? 447 .on::<lsp_types::request::Completion>(handlers::handle_completion)
423 .on::<lsp_types::request::CodeLensRequest>(handlers::handle_code_lens)? 448 .on::<lsp_types::request::CodeLensRequest>(handlers::handle_code_lens)
424 .on::<lsp_types::request::CodeLensResolve>(handlers::handle_code_lens_resolve)? 449 .on::<lsp_types::request::CodeLensResolve>(handlers::handle_code_lens_resolve)
425 .on::<lsp_types::request::FoldingRangeRequest>(handlers::handle_folding_range)? 450 .on::<lsp_types::request::FoldingRangeRequest>(handlers::handle_folding_range)
426 .on::<lsp_types::request::SignatureHelpRequest>(handlers::handle_signature_help)? 451 .on::<lsp_types::request::SignatureHelpRequest>(handlers::handle_signature_help)
427 .on::<lsp_types::request::PrepareRenameRequest>(handlers::handle_prepare_rename)? 452 .on::<lsp_types::request::PrepareRenameRequest>(handlers::handle_prepare_rename)
428 .on::<lsp_types::request::Rename>(handlers::handle_rename)? 453 .on::<lsp_types::request::Rename>(handlers::handle_rename)
429 .on::<lsp_types::request::References>(handlers::handle_references)? 454 .on::<lsp_types::request::References>(handlers::handle_references)
430 .on::<lsp_types::request::Formatting>(handlers::handle_formatting)? 455 .on::<lsp_types::request::Formatting>(handlers::handle_formatting)
431 .on::<lsp_types::request::DocumentHighlightRequest>( 456 .on::<lsp_types::request::DocumentHighlightRequest>(handlers::handle_document_highlight)
432 handlers::handle_document_highlight, 457 .on::<lsp_types::request::CallHierarchyPrepare>(handlers::handle_call_hierarchy_prepare)
433 )?
434 .on::<lsp_types::request::CallHierarchyPrepare>(
435 handlers::handle_call_hierarchy_prepare,
436 )?
437 .on::<lsp_types::request::CallHierarchyIncomingCalls>( 458 .on::<lsp_types::request::CallHierarchyIncomingCalls>(
438 handlers::handle_call_hierarchy_incoming, 459 handlers::handle_call_hierarchy_incoming,
439 )? 460 )
440 .on::<lsp_types::request::CallHierarchyOutgoingCalls>( 461 .on::<lsp_types::request::CallHierarchyOutgoingCalls>(
441 handlers::handle_call_hierarchy_outgoing, 462 handlers::handle_call_hierarchy_outgoing,
442 )? 463 )
443 .on::<lsp_types::request::SemanticTokensFullRequest>( 464 .on::<lsp_types::request::SemanticTokensFullRequest>(
444 handlers::handle_semantic_tokens_full, 465 handlers::handle_semantic_tokens_full,
445 )? 466 )
446 .on::<lsp_types::request::SemanticTokensFullDeltaRequest>( 467 .on::<lsp_types::request::SemanticTokensFullDeltaRequest>(
447 handlers::handle_semantic_tokens_full_delta, 468 handlers::handle_semantic_tokens_full_delta,
448 )? 469 )
449 .on::<lsp_types::request::SemanticTokensRangeRequest>( 470 .on::<lsp_types::request::SemanticTokensRangeRequest>(
450 handlers::handle_semantic_tokens_range, 471 handlers::handle_semantic_tokens_range,
451 )? 472 )
452 .on::<lsp_ext::Ssr>(handlers::handle_ssr)? 473 .on::<lsp_ext::Ssr>(handlers::handle_ssr)
453 .finish(); 474 .finish();
454 Ok(()) 475 Ok(())
455 } 476 }
diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs
index 7df28c9dd..e7991fd28 100644
--- a/crates/rust-analyzer/src/semantic_tokens.rs
+++ b/crates/rust-analyzer/src/semantic_tokens.rs
@@ -101,12 +101,12 @@ pub(crate) struct SemanticTokensBuilder {
101} 101}
102 102
103impl SemanticTokensBuilder { 103impl SemanticTokensBuilder {
104 pub fn new(id: String) -> Self { 104 pub(crate) fn new(id: String) -> Self {
105 SemanticTokensBuilder { id, prev_line: 0, prev_char: 0, data: Default::default() } 105 SemanticTokensBuilder { id, prev_line: 0, prev_char: 0, data: Default::default() }
106 } 106 }
107 107
108 /// Push a new token onto the builder 108 /// Push a new token onto the builder
109 pub fn push(&mut self, range: Range, token_index: u32, modifier_bitset: u32) { 109 pub(crate) fn push(&mut self, range: Range, token_index: u32, modifier_bitset: u32) {
110 let mut push_line = range.start.line as u32; 110 let mut push_line = range.start.line as u32;
111 let mut push_char = range.start.character as u32; 111 let mut push_char = range.start.character as u32;
112 112
@@ -134,12 +134,12 @@ impl SemanticTokensBuilder {
134 self.prev_char = range.start.character as u32; 134 self.prev_char = range.start.character as u32;
135 } 135 }
136 136
137 pub fn build(self) -> SemanticTokens { 137 pub(crate) fn build(self) -> SemanticTokens {
138 SemanticTokens { result_id: Some(self.id), data: self.data } 138 SemanticTokens { result_id: Some(self.id), data: self.data }
139 } 139 }
140} 140}
141 141
142pub fn diff_tokens(old: &[SemanticToken], new: &[SemanticToken]) -> Vec<SemanticTokensEdit> { 142pub(crate) fn diff_tokens(old: &[SemanticToken], new: &[SemanticToken]) -> Vec<SemanticTokensEdit> {
143 let offset = new.iter().zip(old.iter()).take_while(|&(n, p)| n == p).count(); 143 let offset = new.iter().zip(old.iter()).take_while(|&(n, p)| n == p).count();
144 144
145 let (_, old) = old.split_at(offset); 145 let (_, old) = old.split_at(offset);
@@ -165,7 +165,7 @@ pub fn diff_tokens(old: &[SemanticToken], new: &[SemanticToken]) -> Vec<Semantic
165 } 165 }
166} 166}
167 167
168pub fn type_index(type_: SemanticTokenType) -> u32 { 168pub(crate) fn type_index(type_: SemanticTokenType) -> u32 {
169 SUPPORTED_TYPES.iter().position(|it| *it == type_).unwrap() as u32 169 SUPPORTED_TYPES.iter().position(|it| *it == type_).unwrap() as u32
170} 170}
171 171
diff --git a/crates/rust-analyzer/tests/rust-analyzer/support.rs b/crates/rust-analyzer/tests/rust-analyzer/support.rs
index 784cbda79..fe9362bc0 100644
--- a/crates/rust-analyzer/tests/rust-analyzer/support.rs
+++ b/crates/rust-analyzer/tests/rust-analyzer/support.rs
@@ -24,7 +24,7 @@ use vfs::AbsPathBuf;
24 24
25use crate::testdir::TestDir; 25use crate::testdir::TestDir;
26 26
27pub struct Project<'a> { 27pub(crate) struct Project<'a> {
28 fixture: &'a str, 28 fixture: &'a str,
29 with_sysroot: bool, 29 with_sysroot: bool,
30 tmp_dir: Option<TestDir>, 30 tmp_dir: Option<TestDir>,
@@ -33,11 +33,11 @@ pub struct Project<'a> {
33} 33}
34 34
35impl<'a> Project<'a> { 35impl<'a> Project<'a> {
36 pub fn with_fixture(fixture: &str) -> Project { 36 pub(crate) fn with_fixture(fixture: &str) -> Project {
37 Project { fixture, tmp_dir: None, roots: vec![], with_sysroot: false, config: None } 37 Project { fixture, tmp_dir: None, roots: vec![], with_sysroot: false, config: None }
38 } 38 }
39 39
40 pub fn tmp_dir(mut self, tmp_dir: TestDir) -> Project<'a> { 40 pub(crate) fn tmp_dir(mut self, tmp_dir: TestDir) -> Project<'a> {
41 self.tmp_dir = Some(tmp_dir); 41 self.tmp_dir = Some(tmp_dir);
42 self 42 self
43 } 43 }
@@ -47,17 +47,17 @@ impl<'a> Project<'a> {
47 self 47 self
48 } 48 }
49 49
50 pub fn with_sysroot(mut self, sysroot: bool) -> Project<'a> { 50 pub(crate) fn with_sysroot(mut self, sysroot: bool) -> Project<'a> {
51 self.with_sysroot = sysroot; 51 self.with_sysroot = sysroot;
52 self 52 self
53 } 53 }
54 54
55 pub fn with_config(mut self, config: impl Fn(&mut Config) + 'static) -> Project<'a> { 55 pub(crate) fn with_config(mut self, config: impl Fn(&mut Config) + 'static) -> Project<'a> {
56 self.config = Some(Box::new(config)); 56 self.config = Some(Box::new(config));
57 self 57 self
58 } 58 }
59 59
60 pub fn server(self) -> Server { 60 pub(crate) fn server(self) -> Server {
61 let tmp_dir = self.tmp_dir.unwrap_or_else(|| TestDir::new()); 61 let tmp_dir = self.tmp_dir.unwrap_or_else(|| TestDir::new());
62 static INIT: Once = Once::new(); 62 static INIT: Once = Once::new();
63 INIT.call_once(|| { 63 INIT.call_once(|| {
@@ -103,11 +103,11 @@ impl<'a> Project<'a> {
103 } 103 }
104} 104}
105 105
106pub fn project(fixture: &str) -> Server { 106pub(crate) fn project(fixture: &str) -> Server {
107 Project::with_fixture(fixture).server() 107 Project::with_fixture(fixture).server()
108} 108}
109 109
110pub struct Server { 110pub(crate) struct Server {
111 req_id: Cell<u64>, 111 req_id: Cell<u64>,
112 messages: RefCell<Vec<Message>>, 112 messages: RefCell<Vec<Message>>,
113 _thread: jod_thread::JoinHandle<()>, 113 _thread: jod_thread::JoinHandle<()>,
@@ -128,12 +128,12 @@ impl Server {
128 Server { req_id: Cell::new(1), dir, messages: Default::default(), client, _thread } 128 Server { req_id: Cell::new(1), dir, messages: Default::default(), client, _thread }
129 } 129 }
130 130
131 pub fn doc_id(&self, rel_path: &str) -> TextDocumentIdentifier { 131 pub(crate) fn doc_id(&self, rel_path: &str) -> TextDocumentIdentifier {
132 let path = self.dir.path().join(rel_path); 132 let path = self.dir.path().join(rel_path);
133 TextDocumentIdentifier { uri: Url::from_file_path(path).unwrap() } 133 TextDocumentIdentifier { uri: Url::from_file_path(path).unwrap() }
134 } 134 }
135 135
136 pub fn notification<N>(&self, params: N::Params) 136 pub(crate) fn notification<N>(&self, params: N::Params)
137 where 137 where
138 N: lsp_types::notification::Notification, 138 N: lsp_types::notification::Notification,
139 N::Params: Serialize, 139 N::Params: Serialize,
@@ -142,7 +142,7 @@ impl Server {
142 self.send_notification(r) 142 self.send_notification(r)
143 } 143 }
144 144
145 pub fn request<R>(&self, params: R::Params, expected_resp: Value) 145 pub(crate) fn request<R>(&self, params: R::Params, expected_resp: Value)
146 where 146 where
147 R: lsp_types::request::Request, 147 R: lsp_types::request::Request,
148 R::Params: Serialize, 148 R::Params: Serialize,
@@ -159,7 +159,7 @@ impl Server {
159 } 159 }
160 } 160 }
161 161
162 pub fn send_request<R>(&self, params: R::Params) -> Value 162 pub(crate) fn send_request<R>(&self, params: R::Params) -> Value
163 where 163 where
164 R: lsp_types::request::Request, 164 R: lsp_types::request::Request,
165 R::Params: Serialize, 165 R::Params: Serialize,
@@ -202,7 +202,7 @@ impl Server {
202 } 202 }
203 panic!("no response"); 203 panic!("no response");
204 } 204 }
205 pub fn wait_until_workspace_is_loaded(self) -> Server { 205 pub(crate) fn wait_until_workspace_is_loaded(self) -> Server {
206 self.wait_for_message_cond(1, &|msg: &Message| match msg { 206 self.wait_for_message_cond(1, &|msg: &Message| match msg {
207 Message::Notification(n) if n.method == "$/progress" => { 207 Message::Notification(n) if n.method == "$/progress" => {
208 match n.clone().extract::<ProgressParams>("$/progress").unwrap() { 208 match n.clone().extract::<ProgressParams>("$/progress").unwrap() {
@@ -241,7 +241,7 @@ impl Server {
241 self.client.sender.send(Message::Notification(not)).unwrap(); 241 self.client.sender.send(Message::Notification(not)).unwrap();
242 } 242 }
243 243
244 pub fn path(&self) -> &Path { 244 pub(crate) fn path(&self) -> &Path {
245 self.dir.path() 245 self.dir.path()
246 } 246 }
247} 247}
diff --git a/crates/rust-analyzer/tests/rust-analyzer/testdir.rs b/crates/rust-analyzer/tests/rust-analyzer/testdir.rs
index 7487e7429..36271344b 100644
--- a/crates/rust-analyzer/tests/rust-analyzer/testdir.rs
+++ b/crates/rust-analyzer/tests/rust-analyzer/testdir.rs
@@ -4,13 +4,13 @@ use std::{
4 sync::atomic::{AtomicUsize, Ordering}, 4 sync::atomic::{AtomicUsize, Ordering},
5}; 5};
6 6
7pub struct TestDir { 7pub(crate) struct TestDir {
8 path: PathBuf, 8 path: PathBuf,
9 keep: bool, 9 keep: bool,
10} 10}
11 11
12impl TestDir { 12impl TestDir {
13 pub fn new() -> TestDir { 13 pub(crate) fn new() -> TestDir {
14 let base = std::env::temp_dir().join("testdir"); 14 let base = std::env::temp_dir().join("testdir");
15 let pid = std::process::id(); 15 let pid = std::process::id();
16 16
@@ -27,11 +27,11 @@ impl TestDir {
27 panic!("Failed to create a temporary directory") 27 panic!("Failed to create a temporary directory")
28 } 28 }
29 #[allow(unused)] 29 #[allow(unused)]
30 pub fn keep(mut self) -> TestDir { 30 pub(crate) fn keep(mut self) -> TestDir {
31 self.keep = true; 31 self.keep = true;
32 self 32 self
33 } 33 }
34 pub fn path(&self) -> &Path { 34 pub(crate) fn path(&self) -> &Path {
35 &self.path 35 &self.path
36 } 36 }
37} 37}
diff --git a/crates/ssr/src/parsing.rs b/crates/ssr/src/parsing.rs
index 05b66dcd7..f3b084baf 100644
--- a/crates/ssr/src/parsing.rs
+++ b/crates/ssr/src/parsing.rs
@@ -42,7 +42,7 @@ pub(crate) struct Placeholder {
42 42
43/// Represents a `$var` in an SSR query. 43/// Represents a `$var` in an SSR query.
44#[derive(Debug, Clone, PartialEq, Eq, Hash)] 44#[derive(Debug, Clone, PartialEq, Eq, Hash)]
45pub(crate) struct Var(pub String); 45pub(crate) struct Var(pub(crate) String);
46 46
47#[derive(Clone, Debug, PartialEq, Eq)] 47#[derive(Clone, Debug, PartialEq, Eq)]
48pub(crate) enum Constraint { 48pub(crate) enum Constraint {
diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml
index e8de61868..61d2acb49 100644
--- a/crates/syntax/Cargo.toml
+++ b/crates/syntax/Cargo.toml
@@ -13,7 +13,7 @@ doctest = false
13[dependencies] 13[dependencies]
14itertools = "0.9.0" 14itertools = "0.9.0"
15rowan = "0.10.0" 15rowan = "0.10.0"
16rustc_lexer = { version = "685.0.0", package = "rustc-ap-rustc_lexer" } 16rustc_lexer = { version = "686.0.0", package = "rustc-ap-rustc_lexer" }
17rustc-hash = "1.1.0" 17rustc-hash = "1.1.0"
18arrayvec = "0.5.1" 18arrayvec = "0.5.1"
19once_cell = "1.3.1" 19once_cell = "1.3.1"
@@ -27,7 +27,7 @@ serde = { version = "1.0.106", features = ["derive"] }
27stdx = { path = "../stdx", version = "0.0.0" } 27stdx = { path = "../stdx", version = "0.0.0" }
28text_edit = { path = "../text_edit", version = "0.0.0" } 28text_edit = { path = "../text_edit", version = "0.0.0" }
29parser = { path = "../parser", version = "0.0.0" } 29parser = { path = "../parser", version = "0.0.0" }
30test_utils = { path = "../test_utils" } 30test_utils = { path = "../test_utils", version = "0.0.0" }
31 31
32[dev-dependencies] 32[dev-dependencies]
33walkdir = "2.3.1" 33walkdir = "2.3.1"
diff --git a/crates/syntax/src/ast.rs b/crates/syntax/src/ast.rs
index d536bb1e7..8a0e3d27b 100644
--- a/crates/syntax/src/ast.rs
+++ b/crates/syntax/src/ast.rs
@@ -17,7 +17,7 @@ use crate::{
17 17
18pub use self::{ 18pub use self::{
19 expr_ext::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, RangeOp}, 19 expr_ext::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, RangeOp},
20 generated::*, 20 generated::{nodes::*, tokens::*},
21 node_ext::{ 21 node_ext::{
22 AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents, 22 AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents,
23 StructKind, TypeBoundKind, VisibilityKind, 23 StructKind, TypeBoundKind, VisibilityKind,
diff --git a/crates/syntax/src/ast/generated.rs b/crates/syntax/src/ast/generated.rs
index 4a6f41ee7..843b43cf0 100644
--- a/crates/syntax/src/ast/generated.rs
+++ b/crates/syntax/src/ast/generated.rs
@@ -1,8 +1,8 @@
1//! This file is actually hand-written, but the submodules are indeed generated. 1//! This file is actually hand-written, but the submodules are indeed generated.
2#[rustfmt::skip] 2#[rustfmt::skip]
3mod nodes; 3pub(crate) mod nodes;
4#[rustfmt::skip] 4#[rustfmt::skip]
5mod tokens; 5pub(crate) mod tokens;
6 6
7use crate::{ 7use crate::{
8 AstNode, 8 AstNode,
@@ -10,7 +10,7 @@ use crate::{
10 SyntaxNode, 10 SyntaxNode,
11}; 11};
12 12
13pub use {nodes::*, tokens::*}; 13pub(crate) use nodes::*;
14 14
15// Stmt is the only nested enum, so it's easier to just hand-write it 15// Stmt is the only nested enum, so it's easier to just hand-write it
16impl AstNode for Stmt { 16impl AstNode for Stmt {
diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs
index 849a1cdd6..e753b11bb 100644
--- a/crates/syntax/src/lib.rs
+++ b/crates/syntax/src/lib.rs
@@ -46,16 +46,19 @@ use text_edit::Indel;
46pub use crate::{ 46pub use crate::{
47 algo::InsertPosition, 47 algo::InsertPosition,
48 ast::{AstNode, AstToken}, 48 ast::{AstNode, AstToken},
49 parsing::{lex_single_syntax_kind, lex_single_valid_syntax_kind, tokenize, Token}, 49 parsing::lexer::{lex_single_syntax_kind, lex_single_valid_syntax_kind, tokenize, Token},
50 ptr::{AstPtr, SyntaxNodePtr}, 50 ptr::{AstPtr, SyntaxNodePtr},
51 syntax_error::SyntaxError, 51 syntax_error::SyntaxError,
52 syntax_node::{ 52 syntax_node::{
53 Direction, GreenNode, NodeOrToken, SyntaxElement, SyntaxElementChildren, SyntaxNode, 53 SyntaxElement, SyntaxElementChildren, SyntaxNode, SyntaxNodeChildren, SyntaxToken,
54 SyntaxNodeChildren, SyntaxToken, SyntaxTreeBuilder, 54 SyntaxTreeBuilder,
55 }, 55 },
56}; 56};
57pub use parser::{SyntaxKind, T}; 57pub use parser::{SyntaxKind, T};
58pub use rowan::{SmolStr, SyntaxText, TextRange, TextSize, TokenAtOffset, WalkEvent}; 58pub use rowan::{
59 Direction, GreenNode, NodeOrToken, SmolStr, SyntaxText, TextRange, TextSize, TokenAtOffset,
60 WalkEvent,
61};
59 62
60/// `Parse` is the result of the parsing: a syntax tree and a collection of 63/// `Parse` is the result of the parsing: a syntax tree and a collection of
61/// errors. 64/// errors.
diff --git a/crates/syntax/src/parsing.rs b/crates/syntax/src/parsing.rs
index 68a39eb21..333bde54a 100644
--- a/crates/syntax/src/parsing.rs
+++ b/crates/syntax/src/parsing.rs
@@ -1,7 +1,7 @@
1//! Lexing, bridging to parser (which does the actual parsing) and 1//! Lexing, bridging to parser (which does the actual parsing) and
2//! incremental reparsing. 2//! incremental reparsing.
3 3
4mod lexer; 4pub(crate) mod lexer;
5mod text_token_source; 5mod text_token_source;
6mod text_tree_sink; 6mod text_tree_sink;
7mod reparsing; 7mod reparsing;
@@ -10,7 +10,7 @@ use crate::{syntax_node::GreenNode, AstNode, SyntaxError, SyntaxNode};
10use text_token_source::TextTokenSource; 10use text_token_source::TextTokenSource;
11use text_tree_sink::TextTreeSink; 11use text_tree_sink::TextTreeSink;
12 12
13pub use lexer::*; 13pub(crate) use lexer::*;
14 14
15pub(crate) use self::reparsing::incremental_reparse; 15pub(crate) use self::reparsing::incremental_reparse;
16use parser::SyntaxKind; 16use parser::SyntaxKind;
diff --git a/crates/syntax/src/parsing/text_token_source.rs b/crates/syntax/src/parsing/text_token_source.rs
index df866dc2b..0614194a5 100644
--- a/crates/syntax/src/parsing/text_token_source.rs
+++ b/crates/syntax/src/parsing/text_token_source.rs
@@ -65,7 +65,7 @@ fn mk_token(pos: usize, token_offset_pairs: &[(Token, TextSize)]) -> parser::Tok
65 65
66impl<'t> TextTokenSource<'t> { 66impl<'t> TextTokenSource<'t> {
67 /// Generate input from tokens(expect comment and whitespace). 67 /// Generate input from tokens(expect comment and whitespace).
68 pub fn new(text: &'t str, raw_tokens: &'t [Token]) -> TextTokenSource<'t> { 68 pub(crate) fn new(text: &'t str, raw_tokens: &'t [Token]) -> TextTokenSource<'t> {
69 let token_offset_pairs: Vec<_> = raw_tokens 69 let token_offset_pairs: Vec<_> = raw_tokens
70 .iter() 70 .iter()
71 .filter_map({ 71 .filter_map({
diff --git a/crates/syntax/src/syntax_node.rs b/crates/syntax/src/syntax_node.rs
index b2abcbfbb..cc30138fa 100644
--- a/crates/syntax/src/syntax_node.rs
+++ b/crates/syntax/src/syntax_node.rs
@@ -10,9 +10,7 @@ use rowan::{GreenNodeBuilder, Language};
10 10
11use crate::{Parse, SmolStr, SyntaxError, SyntaxKind, TextSize}; 11use crate::{Parse, SmolStr, SyntaxError, SyntaxKind, TextSize};
12 12
13pub use rowan::GreenNode; 13pub(crate) use rowan::{GreenNode, GreenToken, NodeOrToken};
14
15pub(crate) use rowan::GreenToken;
16 14
17#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
18pub enum RustLanguage {} 16pub enum RustLanguage {}
@@ -34,8 +32,6 @@ pub type SyntaxElement = rowan::SyntaxElement<RustLanguage>;
34pub type SyntaxNodeChildren = rowan::SyntaxNodeChildren<RustLanguage>; 32pub type SyntaxNodeChildren = rowan::SyntaxNodeChildren<RustLanguage>;
35pub type SyntaxElementChildren = rowan::SyntaxElementChildren<RustLanguage>; 33pub type SyntaxElementChildren = rowan::SyntaxElementChildren<RustLanguage>;
36 34
37pub use rowan::{Direction, NodeOrToken};
38
39#[derive(Default)] 35#[derive(Default)]
40pub struct SyntaxTreeBuilder { 36pub struct SyntaxTreeBuilder {
41 errors: Vec<SyntaxError>, 37 errors: Vec<SyntaxError>,
diff --git a/crates/vfs/src/vfs_path.rs b/crates/vfs/src/vfs_path.rs
index 022a0be1e..815697597 100644
--- a/crates/vfs/src/vfs_path.rs
+++ b/crates/vfs/src/vfs_path.rs
@@ -120,7 +120,7 @@ impl VfsPath {
120 120
121#[cfg(windows)] 121#[cfg(windows)]
122mod windows_paths { 122mod windows_paths {
123 pub trait Encode { 123 pub(crate) trait Encode {
124 fn encode(&self, buf: &mut Vec<u8>); 124 fn encode(&self, buf: &mut Vec<u8>);
125 } 125 }
126 126
@@ -149,7 +149,7 @@ mod windows_paths {
149 } 149 }
150 } 150 }
151 151
152 pub const SEP: &str = "\\"; 152 pub(crate) const SEP: &str = "\\";
153 const VERBATIM: &str = "\\\\?\\"; 153 const VERBATIM: &str = "\\\\?\\";
154 const UNC: &str = "UNC"; 154 const UNC: &str = "UNC";
155 const DEVICE: &str = "\\\\.\\"; 155 const DEVICE: &str = "\\\\.\\";
@@ -287,7 +287,7 @@ impl VirtualPath {
287 Some(res) 287 Some(res)
288 } 288 }
289 289
290 pub fn name_and_extension(&self) -> Option<(&str, Option<&str>)> { 290 pub(crate) fn name_and_extension(&self) -> Option<(&str, Option<&str>)> {
291 let file_path = if self.0.ends_with('/') { &self.0[..&self.0.len() - 1] } else { &self.0 }; 291 let file_path = if self.0.ends_with('/') { &self.0[..&self.0.len() - 1] } else { &self.0 };
292 let file_name = match file_path.rfind('/') { 292 let file_name = match file_path.rfind('/') {
293 Some(position) => &file_path[position + 1..], 293 Some(position) => &file_path[position + 1..],