diff options
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/Cargo.toml | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/decl_check.rs | 126 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/decl_check/case_conv.rs | 255 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 15 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/unsafe_check.rs | 8 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 149 | ||||
-rw-r--r-- | crates/hir_ty/src/infer.rs | 8 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 37 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 3 | ||||
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 13 | ||||
-rw-r--r-- | crates/hir_ty/src/test_db.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/tests.rs | 8 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 23 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/interner.rs | 37 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 369 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/tls.rs | 162 |
17 files changed, 613 insertions, 614 deletions
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml index be7c812cb..fdc65a5c3 100644 --- a/crates/hir_ty/Cargo.toml +++ b/crates/hir_ty/Cargo.toml | |||
@@ -17,9 +17,9 @@ ena = "0.14.0" | |||
17 | log = "0.4.8" | 17 | log = "0.4.8" |
18 | rustc-hash = "1.1.0" | 18 | rustc-hash = "1.1.0" |
19 | scoped-tls = "1" | 19 | scoped-tls = "1" |
20 | chalk-solve = "0.34" | 20 | chalk-solve = { version = "0.37", default-features = false } |
21 | chalk-ir = "0.34" | 21 | chalk-ir = "0.37" |
22 | chalk-recursive = "0.34" | 22 | chalk-recursive = "0.37" |
23 | 23 | ||
24 | stdx = { path = "../stdx", version = "0.0.0" } | 24 | stdx = { path = "../stdx", version = "0.0.0" } |
25 | hir_def = { path = "../hir_def", version = "0.0.0" } | 25 | hir_def = { path = "../hir_def", version = "0.0.0" } |
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs index f179c62b7..4b3e2fa8f 100644 --- a/crates/hir_ty/src/diagnostics/decl_check.rs +++ b/crates/hir_ty/src/diagnostics/decl_check.rs | |||
@@ -16,7 +16,7 @@ use hir_def::{ | |||
16 | adt::VariantData, | 16 | adt::VariantData, |
17 | expr::{Pat, PatId}, | 17 | expr::{Pat, PatId}, |
18 | src::HasSource, | 18 | src::HasSource, |
19 | AdtId, ConstId, EnumId, FunctionId, Lookup, ModuleDefId, StaticId, StructId, | 19 | AdtId, AttrDefId, ConstId, EnumId, FunctionId, Lookup, ModuleDefId, StaticId, StructId, |
20 | }; | 20 | }; |
21 | use hir_expand::{ | 21 | use hir_expand::{ |
22 | diagnostics::DiagnosticSink, | 22 | diagnostics::DiagnosticSink, |
@@ -32,6 +32,12 @@ use crate::{ | |||
32 | diagnostics::{decl_check::case_conv::*, CaseType, IncorrectCase}, | 32 | diagnostics::{decl_check::case_conv::*, CaseType, IncorrectCase}, |
33 | }; | 33 | }; |
34 | 34 | ||
35 | mod allow { | ||
36 | pub(super) const NON_SNAKE_CASE: &str = "non_snake_case"; | ||
37 | pub(super) const NON_UPPER_CASE_GLOBAL: &str = "non_upper_case_globals"; | ||
38 | pub(super) const NON_CAMEL_CASE_TYPES: &str = "non_camel_case_types"; | ||
39 | } | ||
40 | |||
35 | pub(super) struct DeclValidator<'a, 'b: 'a> { | 41 | pub(super) struct DeclValidator<'a, 'b: 'a> { |
36 | owner: ModuleDefId, | 42 | owner: ModuleDefId, |
37 | sink: &'a mut DiagnosticSink<'b>, | 43 | sink: &'a mut DiagnosticSink<'b>, |
@@ -72,11 +78,29 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
72 | } | 78 | } |
73 | } | 79 | } |
74 | 80 | ||
81 | /// Checks whether not following the convention is allowed for this item. | ||
82 | /// | ||
83 | /// Currently this method doesn't check parent attributes. | ||
84 | fn allowed(&self, db: &dyn HirDatabase, id: AttrDefId, allow_name: &str) -> bool { | ||
85 | db.attrs(id).by_key("allow").tt_values().any(|tt| tt.to_string().contains(allow_name)) | ||
86 | } | ||
87 | |||
75 | fn validate_func(&mut self, db: &dyn HirDatabase, func: FunctionId) { | 88 | fn validate_func(&mut self, db: &dyn HirDatabase, func: FunctionId) { |
76 | let data = db.function_data(func); | 89 | let data = db.function_data(func); |
77 | let body = db.body(func.into()); | 90 | let body = db.body(func.into()); |
78 | 91 | ||
79 | // 1. Check the function name. | 92 | // Recursively validate inner scope items, such as static variables and constants. |
93 | for (item_id, _) in body.item_scope.values() { | ||
94 | let mut validator = DeclValidator::new(item_id, self.sink); | ||
95 | validator.validate_item(db); | ||
96 | } | ||
97 | |||
98 | // Check whether non-snake case identifiers are allowed for this function. | ||
99 | if self.allowed(db, func.into(), allow::NON_SNAKE_CASE) { | ||
100 | return; | ||
101 | } | ||
102 | |||
103 | // Check the function name. | ||
80 | let function_name = data.name.to_string(); | 104 | let function_name = data.name.to_string(); |
81 | let fn_name_replacement = if let Some(new_name) = to_lower_snake_case(&function_name) { | 105 | let fn_name_replacement = if let Some(new_name) = to_lower_snake_case(&function_name) { |
82 | let replacement = Replacement { | 106 | let replacement = Replacement { |
@@ -89,7 +113,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
89 | None | 113 | None |
90 | }; | 114 | }; |
91 | 115 | ||
92 | // 2. Check the param names. | 116 | // Check the param names. |
93 | let mut fn_param_replacements = Vec::new(); | 117 | let mut fn_param_replacements = Vec::new(); |
94 | 118 | ||
95 | for pat_id in body.params.iter().cloned() { | 119 | for pat_id in body.params.iter().cloned() { |
@@ -111,7 +135,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
111 | } | 135 | } |
112 | } | 136 | } |
113 | 137 | ||
114 | // 3. Check the patterns inside the function body. | 138 | // Check the patterns inside the function body. |
115 | let mut pats_replacements = Vec::new(); | 139 | let mut pats_replacements = Vec::new(); |
116 | 140 | ||
117 | for (pat_idx, pat) in body.pats.iter() { | 141 | for (pat_idx, pat) in body.pats.iter() { |
@@ -136,7 +160,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
136 | } | 160 | } |
137 | } | 161 | } |
138 | 162 | ||
139 | // 4. If there is at least one element to spawn a warning on, go to the source map and generate a warning. | 163 | // If there is at least one element to spawn a warning on, go to the source map and generate a warning. |
140 | self.create_incorrect_case_diagnostic_for_func( | 164 | self.create_incorrect_case_diagnostic_for_func( |
141 | func, | 165 | func, |
142 | db, | 166 | db, |
@@ -144,12 +168,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
144 | fn_param_replacements, | 168 | fn_param_replacements, |
145 | ); | 169 | ); |
146 | self.create_incorrect_case_diagnostic_for_variables(func, db, pats_replacements); | 170 | self.create_incorrect_case_diagnostic_for_variables(func, db, pats_replacements); |
147 | |||
148 | // 5. Recursively validate inner scope items, such as static variables and constants. | ||
149 | for (item_id, _) in body.item_scope.values() { | ||
150 | let mut validator = DeclValidator::new(item_id, self.sink); | ||
151 | validator.validate_item(db); | ||
152 | } | ||
153 | } | 171 | } |
154 | 172 | ||
155 | /// Given the information about incorrect names in the function declaration, looks up into the source code | 173 | /// Given the information about incorrect names in the function declaration, looks up into the source code |
@@ -169,7 +187,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
169 | let fn_loc = func.lookup(db.upcast()); | 187 | let fn_loc = func.lookup(db.upcast()); |
170 | let fn_src = fn_loc.source(db.upcast()); | 188 | let fn_src = fn_loc.source(db.upcast()); |
171 | 189 | ||
172 | // 1. Diagnostic for function name. | 190 | // Diagnostic for function name. |
173 | if let Some(replacement) = fn_name_replacement { | 191 | if let Some(replacement) = fn_name_replacement { |
174 | let ast_ptr = match fn_src.value.name() { | 192 | let ast_ptr = match fn_src.value.name() { |
175 | Some(name) => name, | 193 | Some(name) => name, |
@@ -196,7 +214,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
196 | self.sink.push(diagnostic); | 214 | self.sink.push(diagnostic); |
197 | } | 215 | } |
198 | 216 | ||
199 | // 2. Diagnostics for function params. | 217 | // Diagnostics for function params. |
200 | let fn_params_list = match fn_src.value.param_list() { | 218 | let fn_params_list = match fn_src.value.param_list() { |
201 | Some(params) => params, | 219 | Some(params) => params, |
202 | None => { | 220 | None => { |
@@ -312,7 +330,11 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
312 | fn validate_struct(&mut self, db: &dyn HirDatabase, struct_id: StructId) { | 330 | fn validate_struct(&mut self, db: &dyn HirDatabase, struct_id: StructId) { |
313 | let data = db.struct_data(struct_id); | 331 | let data = db.struct_data(struct_id); |
314 | 332 | ||
315 | // 1. Check the structure name. | 333 | let non_camel_case_allowed = |
334 | self.allowed(db, struct_id.into(), allow::NON_CAMEL_CASE_TYPES); | ||
335 | let non_snake_case_allowed = self.allowed(db, struct_id.into(), allow::NON_SNAKE_CASE); | ||
336 | |||
337 | // Check the structure name. | ||
316 | let struct_name = data.name.to_string(); | 338 | let struct_name = data.name.to_string(); |
317 | let struct_name_replacement = if let Some(new_name) = to_camel_case(&struct_name) { | 339 | let struct_name_replacement = if let Some(new_name) = to_camel_case(&struct_name) { |
318 | let replacement = Replacement { | 340 | let replacement = Replacement { |
@@ -320,29 +342,35 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
320 | suggested_text: new_name, | 342 | suggested_text: new_name, |
321 | expected_case: CaseType::UpperCamelCase, | 343 | expected_case: CaseType::UpperCamelCase, |
322 | }; | 344 | }; |
323 | Some(replacement) | 345 | if non_camel_case_allowed { |
346 | None | ||
347 | } else { | ||
348 | Some(replacement) | ||
349 | } | ||
324 | } else { | 350 | } else { |
325 | None | 351 | None |
326 | }; | 352 | }; |
327 | 353 | ||
328 | // 2. Check the field names. | 354 | // Check the field names. |
329 | let mut struct_fields_replacements = Vec::new(); | 355 | let mut struct_fields_replacements = Vec::new(); |
330 | 356 | ||
331 | if let VariantData::Record(fields) = data.variant_data.as_ref() { | 357 | if !non_snake_case_allowed { |
332 | for (_, field) in fields.iter() { | 358 | if let VariantData::Record(fields) = data.variant_data.as_ref() { |
333 | let field_name = field.name.to_string(); | 359 | for (_, field) in fields.iter() { |
334 | if let Some(new_name) = to_lower_snake_case(&field_name) { | 360 | let field_name = field.name.to_string(); |
335 | let replacement = Replacement { | 361 | if let Some(new_name) = to_lower_snake_case(&field_name) { |
336 | current_name: field.name.clone(), | 362 | let replacement = Replacement { |
337 | suggested_text: new_name, | 363 | current_name: field.name.clone(), |
338 | expected_case: CaseType::LowerSnakeCase, | 364 | suggested_text: new_name, |
339 | }; | 365 | expected_case: CaseType::LowerSnakeCase, |
340 | struct_fields_replacements.push(replacement); | 366 | }; |
367 | struct_fields_replacements.push(replacement); | ||
368 | } | ||
341 | } | 369 | } |
342 | } | 370 | } |
343 | } | 371 | } |
344 | 372 | ||
345 | // 3. If there is at least one element to spawn a warning on, go to the source map and generate a warning. | 373 | // If there is at least one element to spawn a warning on, go to the source map and generate a warning. |
346 | self.create_incorrect_case_diagnostic_for_struct( | 374 | self.create_incorrect_case_diagnostic_for_struct( |
347 | struct_id, | 375 | struct_id, |
348 | db, | 376 | db, |
@@ -442,7 +470,12 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
442 | fn validate_enum(&mut self, db: &dyn HirDatabase, enum_id: EnumId) { | 470 | fn validate_enum(&mut self, db: &dyn HirDatabase, enum_id: EnumId) { |
443 | let data = db.enum_data(enum_id); | 471 | let data = db.enum_data(enum_id); |
444 | 472 | ||
445 | // 1. Check the enum name. | 473 | // Check whether non-camel case names are allowed for this enum. |
474 | if self.allowed(db, enum_id.into(), allow::NON_CAMEL_CASE_TYPES) { | ||
475 | return; | ||
476 | } | ||
477 | |||
478 | // Check the enum name. | ||
446 | let enum_name = data.name.to_string(); | 479 | let enum_name = data.name.to_string(); |
447 | let enum_name_replacement = if let Some(new_name) = to_camel_case(&enum_name) { | 480 | let enum_name_replacement = if let Some(new_name) = to_camel_case(&enum_name) { |
448 | let replacement = Replacement { | 481 | let replacement = Replacement { |
@@ -455,7 +488,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
455 | None | 488 | None |
456 | }; | 489 | }; |
457 | 490 | ||
458 | // 2. Check the field names. | 491 | // Check the field names. |
459 | let mut enum_fields_replacements = Vec::new(); | 492 | let mut enum_fields_replacements = Vec::new(); |
460 | 493 | ||
461 | for (_, variant) in data.variants.iter() { | 494 | for (_, variant) in data.variants.iter() { |
@@ -470,7 +503,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
470 | } | 503 | } |
471 | } | 504 | } |
472 | 505 | ||
473 | // 3. If there is at least one element to spawn a warning on, go to the source map and generate a warning. | 506 | // If there is at least one element to spawn a warning on, go to the source map and generate a warning. |
474 | self.create_incorrect_case_diagnostic_for_enum( | 507 | self.create_incorrect_case_diagnostic_for_enum( |
475 | enum_id, | 508 | enum_id, |
476 | db, | 509 | db, |
@@ -572,6 +605,10 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
572 | fn validate_const(&mut self, db: &dyn HirDatabase, const_id: ConstId) { | 605 | fn validate_const(&mut self, db: &dyn HirDatabase, const_id: ConstId) { |
573 | let data = db.const_data(const_id); | 606 | let data = db.const_data(const_id); |
574 | 607 | ||
608 | if self.allowed(db, const_id.into(), allow::NON_UPPER_CASE_GLOBAL) { | ||
609 | return; | ||
610 | } | ||
611 | |||
575 | let name = match &data.name { | 612 | let name = match &data.name { |
576 | Some(name) => name, | 613 | Some(name) => name, |
577 | None => return, | 614 | None => return, |
@@ -612,6 +649,10 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
612 | fn validate_static(&mut self, db: &dyn HirDatabase, static_id: StaticId) { | 649 | fn validate_static(&mut self, db: &dyn HirDatabase, static_id: StaticId) { |
613 | let data = db.static_data(static_id); | 650 | let data = db.static_data(static_id); |
614 | 651 | ||
652 | if self.allowed(db, static_id.into(), allow::NON_UPPER_CASE_GLOBAL) { | ||
653 | return; | ||
654 | } | ||
655 | |||
615 | let name = match &data.name { | 656 | let name = match &data.name { |
616 | Some(name) => name, | 657 | Some(name) => name, |
617 | None => return, | 658 | None => return, |
@@ -854,4 +895,29 @@ fn main() { | |||
854 | "#, | 895 | "#, |
855 | ); | 896 | ); |
856 | } | 897 | } |
898 | |||
899 | #[test] | ||
900 | fn allow_attributes() { | ||
901 | check_diagnostics( | ||
902 | r#" | ||
903 | #[allow(non_snake_case)] | ||
904 | fn NonSnakeCaseName(SOME_VAR: u8) -> u8{ | ||
905 | let OtherVar = SOME_VAR + 1; | ||
906 | OtherVar | ||
907 | } | ||
908 | |||
909 | #[allow(non_snake_case, non_camel_case_types)] | ||
910 | pub struct some_type { | ||
911 | SOME_FIELD: u8, | ||
912 | SomeField: u16, | ||
913 | } | ||
914 | |||
915 | #[allow(non_upper_case_globals)] | ||
916 | pub const some_const: u8 = 10; | ||
917 | |||
918 | #[allow(non_upper_case_globals)] | ||
919 | pub static SomeStatic: u8 = 10; | ||
920 | "#, | ||
921 | ); | ||
922 | } | ||
857 | } | 923 | } |
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 324d60765..14e4d92f0 100644 --- a/crates/hir_ty/src/diagnostics/decl_check/case_conv.rs +++ b/crates/hir_ty/src/diagnostics/decl_check/case_conv.rs | |||
@@ -1,156 +1,145 @@ | |||
1 | //! Functions for string case manipulation, such as detecting the identifier case, | 1 | //! Functions for string case manipulation, such as detecting the identifier case, |
2 | //! and converting it into appropriate form. | 2 | //! and converting it into appropriate form. |
3 | 3 | ||
4 | #[derive(Debug)] | 4 | // Code that was taken from rustc was taken at commit 89fdb30, |
5 | enum DetectedCase { | 5 | // from file /compiler/rustc_lint/src/nonstandard_style.rs |
6 | LowerCamelCase, | ||
7 | UpperCamelCase, | ||
8 | LowerSnakeCase, | ||
9 | UpperSnakeCase, | ||
10 | Unknown, | ||
11 | } | ||
12 | |||
13 | fn detect_case(ident: &str) -> DetectedCase { | ||
14 | let trimmed_ident = ident.trim_matches('_'); | ||
15 | let first_lowercase = trimmed_ident.starts_with(|chr: char| chr.is_ascii_lowercase()); | ||
16 | let mut has_lowercase = first_lowercase; | ||
17 | let mut has_uppercase = false; | ||
18 | let mut has_underscore = false; | ||
19 | |||
20 | for chr in trimmed_ident.chars() { | ||
21 | if chr == '_' { | ||
22 | has_underscore = true; | ||
23 | } else if chr.is_ascii_uppercase() { | ||
24 | has_uppercase = true; | ||
25 | } else if chr.is_ascii_lowercase() { | ||
26 | has_lowercase = true; | ||
27 | } | ||
28 | } | ||
29 | |||
30 | if has_uppercase { | ||
31 | if !has_lowercase { | ||
32 | if has_underscore { | ||
33 | DetectedCase::UpperSnakeCase | ||
34 | } else { | ||
35 | // It has uppercase only and no underscores. Ex: "AABB" | ||
36 | // This is a camel cased acronym. | ||
37 | DetectedCase::UpperCamelCase | ||
38 | } | ||
39 | } else if !has_underscore { | ||
40 | if first_lowercase { | ||
41 | DetectedCase::LowerCamelCase | ||
42 | } else { | ||
43 | DetectedCase::UpperCamelCase | ||
44 | } | ||
45 | } else { | ||
46 | // It has uppercase, it has lowercase, it has underscore. | ||
47 | // No assumptions here | ||
48 | DetectedCase::Unknown | ||
49 | } | ||
50 | } else { | ||
51 | DetectedCase::LowerSnakeCase | ||
52 | } | ||
53 | } | ||
54 | 6 | ||
55 | /// Converts an identifier to an UpperCamelCase form. | 7 | /// Converts an identifier to an UpperCamelCase form. |
56 | /// Returns `None` if the string is already is UpperCamelCase. | 8 | /// Returns `None` if the string is already is UpperCamelCase. |
57 | pub fn to_camel_case(ident: &str) -> Option<String> { | 9 | pub(crate) fn to_camel_case(ident: &str) -> Option<String> { |
58 | let detected_case = detect_case(ident); | 10 | if is_camel_case(ident) { |
59 | 11 | return None; | |
60 | match detected_case { | ||
61 | DetectedCase::UpperCamelCase => return None, | ||
62 | DetectedCase::LowerCamelCase => { | ||
63 | let mut first_capitalized = false; | ||
64 | let output = ident | ||
65 | .chars() | ||
66 | .map(|chr| { | ||
67 | if !first_capitalized && chr.is_ascii_lowercase() { | ||
68 | first_capitalized = true; | ||
69 | chr.to_ascii_uppercase() | ||
70 | } else { | ||
71 | chr | ||
72 | } | ||
73 | }) | ||
74 | .collect(); | ||
75 | return Some(output); | ||
76 | } | ||
77 | _ => {} | ||
78 | } | 12 | } |
79 | 13 | ||
80 | let mut output = String::with_capacity(ident.len()); | 14 | // Taken from rustc. |
81 | 15 | let ret = ident | |
82 | let mut capital_added = false; | 16 | .trim_matches('_') |
83 | for chr in ident.chars() { | 17 | .split('_') |
84 | if chr.is_alphabetic() { | 18 | .filter(|component| !component.is_empty()) |
85 | if !capital_added { | 19 | .map(|component| { |
86 | output.push(chr.to_ascii_uppercase()); | 20 | let mut camel_cased_component = String::new(); |
87 | capital_added = true; | 21 | |
88 | } else { | 22 | let mut new_word = true; |
89 | output.push(chr.to_ascii_lowercase()); | 23 | let mut prev_is_lower_case = true; |
24 | |||
25 | for c in component.chars() { | ||
26 | // Preserve the case if an uppercase letter follows a lowercase letter, so that | ||
27 | // `camelCase` is converted to `CamelCase`. | ||
28 | if prev_is_lower_case && c.is_uppercase() { | ||
29 | new_word = true; | ||
30 | } | ||
31 | |||
32 | if new_word { | ||
33 | camel_cased_component.push_str(&c.to_uppercase().to_string()); | ||
34 | } else { | ||
35 | camel_cased_component.push_str(&c.to_lowercase().to_string()); | ||
36 | } | ||
37 | |||
38 | prev_is_lower_case = c.is_lowercase(); | ||
39 | new_word = false; | ||
90 | } | 40 | } |
91 | } else if chr == '_' { | ||
92 | // Skip this character and make the next one capital. | ||
93 | capital_added = false; | ||
94 | } else { | ||
95 | // Put the characted as-is. | ||
96 | output.push(chr); | ||
97 | } | ||
98 | } | ||
99 | 41 | ||
100 | if output == ident { | 42 | camel_cased_component |
101 | // While we didn't detect the correct case at the beginning, there | 43 | }) |
102 | // may be special cases: e.g. `A` is both valid CamelCase and UPPER_SNAKE_CASE. | 44 | .fold((String::new(), None), |(acc, prev): (String, Option<String>), next| { |
103 | None | 45 | // separate two components with an underscore if their boundary cannot |
104 | } else { | 46 | // be distinguished using a uppercase/lowercase case distinction |
105 | Some(output) | 47 | let join = if let Some(prev) = prev { |
106 | } | 48 | let l = prev.chars().last().unwrap(); |
49 | let f = next.chars().next().unwrap(); | ||
50 | !char_has_case(l) && !char_has_case(f) | ||
51 | } else { | ||
52 | false | ||
53 | }; | ||
54 | (acc + if join { "_" } else { "" } + &next, Some(next)) | ||
55 | }) | ||
56 | .0; | ||
57 | Some(ret) | ||
107 | } | 58 | } |
108 | 59 | ||
109 | /// Converts an identifier to a lower_snake_case form. | 60 | /// Converts an identifier to a lower_snake_case form. |
110 | /// Returns `None` if the string is already in lower_snake_case. | 61 | /// Returns `None` if the string is already in lower_snake_case. |
111 | pub fn to_lower_snake_case(ident: &str) -> Option<String> { | 62 | pub(crate) fn to_lower_snake_case(ident: &str) -> Option<String> { |
112 | // First, assume that it's UPPER_SNAKE_CASE. | 63 | if is_lower_snake_case(ident) { |
113 | match detect_case(ident) { | 64 | return None; |
114 | DetectedCase::LowerSnakeCase => return None, | 65 | } else if is_upper_snake_case(ident) { |
115 | DetectedCase::UpperSnakeCase => { | 66 | return Some(ident.to_lowercase()); |
116 | return Some(ident.chars().map(|chr| chr.to_ascii_lowercase()).collect()) | ||
117 | } | ||
118 | _ => {} | ||
119 | } | 67 | } |
120 | 68 | ||
121 | // Otherwise, assume that it's CamelCase. | 69 | Some(stdx::to_lower_snake_case(ident)) |
122 | let lower_snake_case = stdx::to_lower_snake_case(ident); | ||
123 | |||
124 | if lower_snake_case == ident { | ||
125 | // While we didn't detect the correct case at the beginning, there | ||
126 | // may be special cases: e.g. `a` is both valid camelCase and snake_case. | ||
127 | None | ||
128 | } else { | ||
129 | Some(lower_snake_case) | ||
130 | } | ||
131 | } | 70 | } |
132 | 71 | ||
133 | /// Converts an identifier to an UPPER_SNAKE_CASE form. | 72 | /// Converts an identifier to an UPPER_SNAKE_CASE form. |
134 | /// Returns `None` if the string is already is UPPER_SNAKE_CASE. | 73 | /// Returns `None` if the string is already is UPPER_SNAKE_CASE. |
135 | pub fn to_upper_snake_case(ident: &str) -> Option<String> { | 74 | pub(crate) fn to_upper_snake_case(ident: &str) -> Option<String> { |
136 | match detect_case(ident) { | 75 | if is_upper_snake_case(ident) { |
137 | DetectedCase::UpperSnakeCase => return None, | 76 | return None; |
138 | DetectedCase::LowerSnakeCase => { | 77 | } else if is_lower_snake_case(ident) { |
139 | return Some(ident.chars().map(|chr| chr.to_ascii_uppercase()).collect()) | 78 | return Some(ident.to_uppercase()); |
140 | } | 79 | } |
141 | _ => {} | 80 | |
81 | Some(stdx::to_upper_snake_case(ident)) | ||
82 | } | ||
83 | |||
84 | // Taken from rustc. | ||
85 | // Modified by replacing the use of unstable feature `array_windows`. | ||
86 | fn is_camel_case(name: &str) -> bool { | ||
87 | let name = name.trim_matches('_'); | ||
88 | if name.is_empty() { | ||
89 | return true; | ||
142 | } | 90 | } |
143 | 91 | ||
144 | // Normalize the string from whatever form it's in currently, and then just make it uppercase. | 92 | let mut fst = None; |
145 | let upper_snake_case = stdx::to_upper_snake_case(ident); | 93 | // start with a non-lowercase letter rather than non-uppercase |
94 | // ones (some scripts don't have a concept of upper/lowercase) | ||
95 | !name.chars().next().unwrap().is_lowercase() | ||
96 | && !name.contains("__") | ||
97 | && !name.chars().any(|snd| { | ||
98 | let ret = match (fst, snd) { | ||
99 | (None, _) => false, | ||
100 | (Some(fst), snd) => { | ||
101 | char_has_case(fst) && snd == '_' || char_has_case(snd) && fst == '_' | ||
102 | } | ||
103 | }; | ||
104 | fst = Some(snd); | ||
105 | |||
106 | ret | ||
107 | }) | ||
108 | } | ||
109 | |||
110 | fn is_lower_snake_case(ident: &str) -> bool { | ||
111 | is_snake_case(ident, char::is_uppercase) | ||
112 | } | ||
146 | 113 | ||
147 | if upper_snake_case == ident { | 114 | fn is_upper_snake_case(ident: &str) -> bool { |
148 | // While we didn't detect the correct case at the beginning, there | 115 | is_snake_case(ident, char::is_lowercase) |
149 | // may be special cases: e.g. `A` is both valid CamelCase and UPPER_SNAKE_CASE. | 116 | } |
150 | None | 117 | |
151 | } else { | 118 | // Taken from rustc. |
152 | Some(upper_snake_case) | 119 | // Modified to allow checking for both upper and lower snake case. |
120 | fn is_snake_case<F: Fn(char) -> bool>(ident: &str, wrong_case: F) -> bool { | ||
121 | if ident.is_empty() { | ||
122 | return true; | ||
153 | } | 123 | } |
124 | let ident = ident.trim_matches('_'); | ||
125 | |||
126 | let mut allow_underscore = true; | ||
127 | ident.chars().all(|c| { | ||
128 | allow_underscore = match c { | ||
129 | '_' if !allow_underscore => return false, | ||
130 | '_' => false, | ||
131 | // It would be more obvious to check for the correct case, | ||
132 | // but some characters do not have a case. | ||
133 | c if !wrong_case(c) => true, | ||
134 | _ => return false, | ||
135 | }; | ||
136 | true | ||
137 | }) | ||
138 | } | ||
139 | |||
140 | // Taken from rustc. | ||
141 | fn char_has_case(c: char) -> bool { | ||
142 | c.is_lowercase() || c.is_uppercase() | ||
154 | } | 143 | } |
155 | 144 | ||
156 | #[cfg(test)] | 145 | #[cfg(test)] |
@@ -173,6 +162,7 @@ mod tests { | |||
173 | check(to_lower_snake_case, "CamelCase", expect![["camel_case"]]); | 162 | check(to_lower_snake_case, "CamelCase", expect![["camel_case"]]); |
174 | check(to_lower_snake_case, "lowerCamelCase", expect![["lower_camel_case"]]); | 163 | check(to_lower_snake_case, "lowerCamelCase", expect![["lower_camel_case"]]); |
175 | check(to_lower_snake_case, "a", expect![[""]]); | 164 | check(to_lower_snake_case, "a", expect![[""]]); |
165 | check(to_lower_snake_case, "abc", expect![[""]]); | ||
176 | } | 166 | } |
177 | 167 | ||
178 | #[test] | 168 | #[test] |
@@ -187,6 +177,11 @@ mod tests { | |||
187 | check(to_camel_case, "name", expect![["Name"]]); | 177 | check(to_camel_case, "name", expect![["Name"]]); |
188 | check(to_camel_case, "A", expect![[""]]); | 178 | check(to_camel_case, "A", expect![[""]]); |
189 | check(to_camel_case, "AABB", expect![[""]]); | 179 | check(to_camel_case, "AABB", expect![[""]]); |
180 | // Taken from rustc: /compiler/rustc_lint/src/nonstandard_style/tests.rs | ||
181 | check(to_camel_case, "X86_64", expect![[""]]); | ||
182 | check(to_camel_case, "x86__64", expect![["X86_64"]]); | ||
183 | check(to_camel_case, "Abc_123", expect![["Abc123"]]); | ||
184 | check(to_camel_case, "A1_b2_c3", expect![["A1B2C3"]]); | ||
190 | } | 185 | } |
191 | 186 | ||
192 | #[test] | 187 | #[test] |
@@ -197,5 +192,7 @@ mod tests { | |||
197 | check(to_upper_snake_case, "CamelCase", expect![["CAMEL_CASE"]]); | 192 | check(to_upper_snake_case, "CamelCase", expect![["CAMEL_CASE"]]); |
198 | check(to_upper_snake_case, "lowerCamelCase", expect![["LOWER_CAMEL_CASE"]]); | 193 | check(to_upper_snake_case, "lowerCamelCase", expect![["LOWER_CAMEL_CASE"]]); |
199 | check(to_upper_snake_case, "A", expect![[""]]); | 194 | check(to_upper_snake_case, "A", expect![[""]]); |
195 | check(to_upper_snake_case, "ABC", expect![[""]]); | ||
196 | check(to_upper_snake_case, "X86_64", expect![[""]]); | ||
200 | } | 197 | } |
201 | } | 198 | } |
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 | ||
20 | pub use hir_def::{ | 20 | pub(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 | ||
33 | pub(super) struct ExprValidator<'a, 'b: 'a> { | 26 | pub(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 | ||
62 | pub struct UnsafeExpr { | 62 | pub(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 | ||
67 | pub fn unsafe_expressions( | 67 | pub(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 | ||
87 | impl<'a> HirFormatter<'a> { | 115 | impl<'a> HirFormatter<'a> { |
@@ -126,7 +154,7 @@ impl<'a> HirFormatter<'a> { | |||
126 | } | 154 | } |
127 | 155 | ||
128 | #[derive(Clone, Copy)] | 156 | #[derive(Clone, Copy)] |
129 | enum DisplayTarget { | 157 | pub 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 | ||
139 | impl DisplayTarget { | 169 | impl 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 { | |||
654 | impl HirDisplay for Obligation { | 710 | impl 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 | ||
96 | impl BindingMode { | 96 | impl 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)] |
216 | struct BreakableContext { | 216 | struct 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 | ||
222 | fn find_breakable<'c>( | 222 | fn 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)] |
37 | pub(super) struct Canonicalized<T> { | 37 | pub(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 | ||
129 | impl<T> Canonicalized<T> { | 129 | impl<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 | ||
167 | pub fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> { | 171 | pub(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 | ||
201 | impl InferenceTable { | 205 | impl 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)] |
5 | macro_rules! eprintln { | 4 | macro_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)] |
1117 | pub(crate) struct ReturnTypeImplTrait { | 1116 | pub(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/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 8961df404..5a6f0c67f 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -740,6 +740,19 @@ pub fn implements_trait( | |||
740 | solution.is_some() | 740 | solution.is_some() |
741 | } | 741 | } |
742 | 742 | ||
743 | pub fn implements_trait_unique( | ||
744 | ty: &Canonical<Ty>, | ||
745 | db: &dyn HirDatabase, | ||
746 | env: Arc<TraitEnvironment>, | ||
747 | krate: CrateId, | ||
748 | trait_: TraitId, | ||
749 | ) -> bool { | ||
750 | let goal = generic_implements_goal(db, env, trait_, ty.clone()); | ||
751 | let solution = db.trait_solve(krate, goal); | ||
752 | |||
753 | matches!(solution, Some(crate::traits::Solution::Unique(_))) | ||
754 | } | ||
755 | |||
743 | /// This creates Substs for a trait with the given Self type and type variables | 756 | /// This creates Substs for a trait with the given Self type and type variables |
744 | /// for all other parameters, to query Chalk with it. | 757 | /// for all other parameters, to query Chalk with it. |
745 | fn generic_implements_goal( | 758 | fn generic_implements_goal( |
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)] |
24 | pub struct TestDB { | 24 | pub(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 | ||
115 | impl TestDB { | 115 | impl 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 | ||
4 | use log::debug; | 4 | use log::debug; |
5 | 5 | ||
6 | use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg, TypeName}; | 6 | use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg}; |
7 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; | 7 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; |
8 | 8 | ||
9 | use base_db::{salsa::InternKey, CrateId}; | 9 | use base_db::{salsa::InternKey, CrateId}; |
@@ -27,7 +27,7 @@ use mapping::{ | |||
27 | TypeAliasAsValue, | 27 | TypeAliasAsValue, |
28 | }; | 28 | }; |
29 | 29 | ||
30 | pub use self::interner::*; | 30 | pub(crate) use self::interner::*; |
31 | 31 | ||
32 | pub(super) mod tls; | 32 | pub(super) mod tls; |
33 | mod interner; | 33 | mod 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)] |
11 | pub struct Interner; | 11 | pub struct Interner; |
12 | 12 | ||
13 | pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>; | 13 | pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>; |
14 | pub type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; | 14 | pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; |
15 | pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>; | 15 | pub(crate) type ForeignDefId = chalk_ir::ForeignDefId<Interner>; |
16 | pub type TraitId = chalk_ir::TraitId<Interner>; | 16 | pub(crate) type TraitId = chalk_ir::TraitId<Interner>; |
17 | pub type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>; | 17 | pub(crate) type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>; |
18 | pub type AdtId = chalk_ir::AdtId<Interner>; | 18 | pub(crate) type AdtId = chalk_ir::AdtId<Interner>; |
19 | pub type StructDatum = chalk_solve::rust_ir::AdtDatum<Interner>; | 19 | pub(crate) type StructDatum = chalk_solve::rust_ir::AdtDatum<Interner>; |
20 | pub type ImplId = chalk_ir::ImplId<Interner>; | 20 | pub(crate) type ImplId = chalk_ir::ImplId<Interner>; |
21 | pub type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>; | 21 | pub(crate) type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>; |
22 | pub type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>; | 22 | pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>; |
23 | pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; | 23 | pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; |
24 | pub type FnDefId = chalk_ir::FnDefId<Interner>; | 24 | pub(crate) type FnDefId = chalk_ir::FnDefId<Interner>; |
25 | pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; | 25 | pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; |
26 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | 26 | pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; |
27 | pub type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; | 27 | pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; |
28 | 28 | ||
29 | impl chalk_ir::interner::Interner for Interner { | 29 | impl 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 be3301313..86cbc4c7e 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -4,7 +4,7 @@ | |||
4 | //! conversions. | 4 | //! conversions. |
5 | 5 | ||
6 | use chalk_ir::{ | 6 | use chalk_ir::{ |
7 | cast::Cast, fold::shift::Shift, interner::HasInterner, PlaceholderIndex, Scalar, TypeName, | 7 | cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, Scalar, |
8 | UniverseIndex, | 8 | UniverseIndex, |
9 | }; | 9 | }; |
10 | use chalk_solve::rust_ir; | 10 | use chalk_solve::rust_ir; |
@@ -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( |
@@ -76,57 +134,47 @@ impl ToChalk for Ty { | |||
76 | ); | 134 | ); |
77 | let bounded_ty = chalk_ir::DynTy { | 135 | let bounded_ty = chalk_ir::DynTy { |
78 | bounds: make_binders(where_clauses, 1), | 136 | bounds: make_binders(where_clauses, 1), |
79 | lifetime: FAKE_PLACEHOLDER.to_lifetime(&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,12 +205,75 @@ 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 | ||
164 | const FAKE_PLACEHOLDER: PlaceholderIndex = | 270 | fn apply_ty_from_chalk( |
165 | PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX }; | 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 | } | ||
166 | 277 | ||
167 | /// 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 |
168 | /// 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. |
@@ -172,57 +283,22 @@ fn ref_to_chalk( | |||
172 | subst: Substs, | 283 | subst: Substs, |
173 | ) -> chalk_ir::Ty<Interner> { | 284 | ) -> chalk_ir::Ty<Interner> { |
174 | let arg = subst[0].clone().to_chalk(db); | 285 | let arg = subst[0].clone().to_chalk(db); |
175 | let lifetime = FAKE_PLACEHOLDER.to_lifetime(&Interner); | 286 | let lifetime = LifetimeData::Static.intern(&Interner); |
176 | chalk_ir::ApplicationTy { | 287 | chalk_ir::TyKind::Ref(mutability.to_chalk(db), lifetime, arg).intern(&Interner) |
177 | name: TypeName::Ref(mutability.to_chalk(db)), | ||
178 | substitution: chalk_ir::Substitution::from_iter( | ||
179 | &Interner, | ||
180 | vec![lifetime.cast(&Interner), arg.cast(&Interner)], | ||
181 | ), | ||
182 | } | ||
183 | .intern(&Interner) | ||
184 | } | ||
185 | |||
186 | /// Here we remove the lifetime from the type we got from Chalk. | ||
187 | fn ref_from_chalk( | ||
188 | db: &dyn HirDatabase, | ||
189 | mutability: chalk_ir::Mutability, | ||
190 | subst: chalk_ir::Substitution<Interner>, | ||
191 | ) -> Ty { | ||
192 | let tys = subst | ||
193 | .iter(&Interner) | ||
194 | .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone()))) | ||
195 | .collect(); | ||
196 | Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys)) | ||
197 | } | 288 | } |
198 | 289 | ||
199 | /// 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 |
200 | /// 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. |
201 | fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> { | 292 | fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> { |
202 | let arg = subst[0].clone().to_chalk(db); | 293 | let arg = subst[0].clone().to_chalk(db); |
203 | let usize_ty = chalk_ir::ApplicationTy { | 294 | let usize_ty = |
204 | name: TypeName::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)), | 295 | chalk_ir::TyKind::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)).intern(&Interner); |
205 | substitution: chalk_ir::Substitution::empty(&Interner), | 296 | let const_ = chalk_ir::ConstData { |
297 | ty: usize_ty, | ||
298 | value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }), | ||
206 | } | 299 | } |
207 | .intern(&Interner); | 300 | .intern(&Interner); |
208 | let const_ = FAKE_PLACEHOLDER.to_const(&Interner, usize_ty); | 301 | chalk_ir::TyKind::Array(arg, const_).intern(&Interner) |
209 | chalk_ir::ApplicationTy { | ||
210 | name: TypeName::Array, | ||
211 | substitution: chalk_ir::Substitution::from_iter( | ||
212 | &Interner, | ||
213 | vec![arg.cast(&Interner), const_.cast(&Interner)], | ||
214 | ), | ||
215 | } | ||
216 | .intern(&Interner) | ||
217 | } | ||
218 | |||
219 | /// Here we remove the const from the type we got from Chalk. | ||
220 | fn array_from_chalk(db: &dyn HirDatabase, subst: chalk_ir::Substitution<Interner>) -> Ty { | ||
221 | let tys = subst | ||
222 | .iter(&Interner) | ||
223 | .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone()))) | ||
224 | .collect(); | ||
225 | Ty::apply(TypeCtor::Array, Substs(tys)) | ||
226 | } | 302 | } |
227 | 303 | ||
228 | impl ToChalk for Substs { | 304 | impl ToChalk for Substs { |
@@ -287,124 +363,6 @@ impl ToChalk for OpaqueTyId { | |||
287 | } | 363 | } |
288 | } | 364 | } |
289 | 365 | ||
290 | impl ToChalk for TypeCtor { | ||
291 | type Chalk = TypeName<Interner>; | ||
292 | |||
293 | fn to_chalk(self, db: &dyn HirDatabase) -> TypeName<Interner> { | ||
294 | match self { | ||
295 | TypeCtor::AssociatedType(type_alias) => { | ||
296 | let assoc_type = TypeAliasAsAssocType(type_alias); | ||
297 | let assoc_type_id = assoc_type.to_chalk(db); | ||
298 | TypeName::AssociatedType(assoc_type_id) | ||
299 | } | ||
300 | |||
301 | TypeCtor::OpaqueType(impl_trait_id) => { | ||
302 | let id = impl_trait_id.to_chalk(db); | ||
303 | TypeName::OpaqueType(id) | ||
304 | } | ||
305 | |||
306 | TypeCtor::ForeignType(type_alias) => { | ||
307 | let foreign_type = TypeAliasAsForeignType(type_alias); | ||
308 | let foreign_type_id = foreign_type.to_chalk(db); | ||
309 | TypeName::Foreign(foreign_type_id) | ||
310 | } | ||
311 | |||
312 | TypeCtor::Bool => TypeName::Scalar(Scalar::Bool), | ||
313 | TypeCtor::Char => TypeName::Scalar(Scalar::Char), | ||
314 | TypeCtor::Int(int_ty) => TypeName::Scalar(int_ty_to_chalk(int_ty)), | ||
315 | TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => { | ||
316 | TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) | ||
317 | } | ||
318 | TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => { | ||
319 | TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) | ||
320 | } | ||
321 | |||
322 | TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()), | ||
323 | TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)), | ||
324 | TypeCtor::Slice => TypeName::Slice, | ||
325 | TypeCtor::Array => TypeName::Array, | ||
326 | TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)), | ||
327 | TypeCtor::Str => TypeName::Str, | ||
328 | TypeCtor::FnDef(callable_def) => { | ||
329 | let id = callable_def.to_chalk(db); | ||
330 | TypeName::FnDef(id) | ||
331 | } | ||
332 | TypeCtor::Never => TypeName::Never, | ||
333 | |||
334 | TypeCtor::Closure { def, expr } => { | ||
335 | let closure_id = db.intern_closure((def, expr)); | ||
336 | TypeName::Closure(closure_id.into()) | ||
337 | } | ||
338 | |||
339 | TypeCtor::Adt(adt_id) => TypeName::Adt(chalk_ir::AdtId(adt_id)), | ||
340 | |||
341 | TypeCtor::FnPtr { .. } => { | ||
342 | // This should not be reached, since Chalk doesn't represent | ||
343 | // function pointers with TypeName | ||
344 | unreachable!() | ||
345 | } | ||
346 | } | ||
347 | } | ||
348 | |||
349 | fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor { | ||
350 | match type_name { | ||
351 | TypeName::Adt(struct_id) => TypeCtor::Adt(struct_id.0), | ||
352 | TypeName::AssociatedType(type_id) => { | ||
353 | TypeCtor::AssociatedType(from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0) | ||
354 | } | ||
355 | TypeName::OpaqueType(opaque_type_id) => { | ||
356 | TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)) | ||
357 | } | ||
358 | |||
359 | TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool, | ||
360 | TypeName::Scalar(Scalar::Char) => TypeCtor::Char, | ||
361 | TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(IntTy { | ||
362 | signedness: Signedness::Signed, | ||
363 | bitness: bitness_from_chalk_int(int_ty), | ||
364 | }), | ||
365 | TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(IntTy { | ||
366 | signedness: Signedness::Unsigned, | ||
367 | bitness: bitness_from_chalk_uint(uint_ty), | ||
368 | }), | ||
369 | TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => { | ||
370 | TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) | ||
371 | } | ||
372 | TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => { | ||
373 | TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) | ||
374 | } | ||
375 | TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 }, | ||
376 | TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)), | ||
377 | TypeName::Slice => TypeCtor::Slice, | ||
378 | TypeName::Ref(mutability) => TypeCtor::Ref(from_chalk(db, mutability)), | ||
379 | TypeName::Str => TypeCtor::Str, | ||
380 | TypeName::Never => TypeCtor::Never, | ||
381 | |||
382 | TypeName::FnDef(fn_def_id) => { | ||
383 | let callable_def = from_chalk(db, fn_def_id); | ||
384 | TypeCtor::FnDef(callable_def) | ||
385 | } | ||
386 | TypeName::Array => TypeCtor::Array, | ||
387 | |||
388 | TypeName::Closure(id) => { | ||
389 | let id: crate::db::ClosureId = id.into(); | ||
390 | let (def, expr) = db.lookup_intern_closure(id); | ||
391 | TypeCtor::Closure { def, expr } | ||
392 | } | ||
393 | |||
394 | TypeName::Foreign(foreign_def_id) => { | ||
395 | TypeCtor::ForeignType(from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0) | ||
396 | } | ||
397 | |||
398 | TypeName::Error => { | ||
399 | // this should not be reached, since we don't represent TypeName::Error with TypeCtor | ||
400 | unreachable!() | ||
401 | } | ||
402 | TypeName::Generator(_) => unimplemented!(), // FIXME | ||
403 | TypeName::GeneratorWitness(_) => unimplemented!(), // FIXME | ||
404 | } | ||
405 | } | ||
406 | } | ||
407 | |||
408 | fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness { | 366 | fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness { |
409 | use chalk_ir::UintTy; | 367 | use chalk_ir::UintTy; |
410 | 368 | ||
@@ -506,7 +464,7 @@ impl ToChalk for CallableDefId { | |||
506 | } | 464 | } |
507 | } | 465 | } |
508 | 466 | ||
509 | pub struct TypeAliasAsAssocType(pub TypeAliasId); | 467 | pub(crate) struct TypeAliasAsAssocType(pub(crate) TypeAliasId); |
510 | 468 | ||
511 | impl ToChalk for TypeAliasAsAssocType { | 469 | impl ToChalk for TypeAliasAsAssocType { |
512 | type Chalk = AssocTypeId; | 470 | type Chalk = AssocTypeId; |
@@ -520,7 +478,7 @@ impl ToChalk for TypeAliasAsAssocType { | |||
520 | } | 478 | } |
521 | } | 479 | } |
522 | 480 | ||
523 | pub struct TypeAliasAsForeignType(pub TypeAliasId); | 481 | pub(crate) struct TypeAliasAsForeignType(pub(crate) TypeAliasId); |
524 | 482 | ||
525 | impl ToChalk for TypeAliasAsForeignType { | 483 | impl ToChalk for TypeAliasAsForeignType { |
526 | type Chalk = ForeignDefId; | 484 | type Chalk = ForeignDefId; |
@@ -534,7 +492,7 @@ impl ToChalk for TypeAliasAsForeignType { | |||
534 | } | 492 | } |
535 | } | 493 | } |
536 | 494 | ||
537 | pub struct TypeAliasAsValue(pub TypeAliasId); | 495 | pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId); |
538 | 496 | ||
539 | impl ToChalk for TypeAliasAsValue { | 497 | impl ToChalk for TypeAliasAsValue { |
540 | type Chalk = AssociatedTyValueId; | 498 | type Chalk = AssociatedTyValueId; |
@@ -676,9 +634,9 @@ where | |||
676 | .kinds | 634 | .kinds |
677 | .iter() | 635 | .iter() |
678 | .map(|k| match k { | 636 | .map(|k| match k { |
679 | TyKind::General => chalk_ir::TyKind::General, | 637 | TyKind::General => chalk_ir::TyVariableKind::General, |
680 | TyKind::Integer => chalk_ir::TyKind::Integer, | 638 | TyKind::Integer => chalk_ir::TyVariableKind::Integer, |
681 | TyKind::Float => chalk_ir::TyKind::Float, | 639 | TyKind::Float => chalk_ir::TyVariableKind::Float, |
682 | }) | 640 | }) |
683 | .map(|tk| { | 641 | .map(|tk| { |
684 | chalk_ir::CanonicalVarKind::new( | 642 | chalk_ir::CanonicalVarKind::new( |
@@ -699,9 +657,9 @@ where | |||
699 | .iter(&Interner) | 657 | .iter(&Interner) |
700 | .map(|k| match k.kind { | 658 | .map(|k| match k.kind { |
701 | chalk_ir::VariableKind::Ty(tk) => match tk { | 659 | chalk_ir::VariableKind::Ty(tk) => match tk { |
702 | chalk_ir::TyKind::General => TyKind::General, | 660 | chalk_ir::TyVariableKind::General => TyKind::General, |
703 | chalk_ir::TyKind::Integer => TyKind::Integer, | 661 | chalk_ir::TyVariableKind::Integer => TyKind::Integer, |
704 | chalk_ir::TyKind::Float => TyKind::Float, | 662 | chalk_ir::TyVariableKind::Float => TyKind::Float, |
705 | }, | 663 | }, |
706 | chalk_ir::VariableKind::Lifetime => panic!("unexpected lifetime from Chalk"), | 664 | chalk_ir::VariableKind::Lifetime => panic!("unexpected lifetime from Chalk"), |
707 | chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"), | 665 | chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"), |
@@ -767,7 +725,8 @@ where | |||
767 | chalk_ir::Binders::new( | 725 | chalk_ir::Binders::new( |
768 | chalk_ir::VariableKinds::from_iter( | 726 | chalk_ir::VariableKinds::from_iter( |
769 | &Interner, | 727 | &Interner, |
770 | 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), | ||
771 | ), | 730 | ), |
772 | value, | 731 | value, |
773 | ) | 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. |
2 | use std::fmt; | 2 | use std::fmt; |
3 | 3 | ||
4 | use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication, TypeName}; | 4 | use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication}; |
5 | use itertools::Itertools; | 5 | use itertools::Itertools; |
6 | 6 | ||
7 | use super::{from_chalk, Interner, TypeAliasAsAssocType}; | 7 | use super::{from_chalk, Interner, TypeAliasAsAssocType}; |
8 | use crate::{db::HirDatabase, CallableDefId, TypeCtor}; | 8 | use crate::{db::HirDatabase, CallableDefId}; |
9 | use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId}; | 9 | use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId}; |
10 | 10 | ||
11 | pub use unsafe_tls::{set_current_program, with_current_program}; | 11 | pub(crate) use unsafe_tls::{set_current_program, with_current_program}; |
12 | 12 | ||
13 | pub struct DebugContext<'a>(&'a dyn HirDatabase); | 13 | pub(crate) struct DebugContext<'a>(&'a dyn HirDatabase); |
14 | 14 | ||
15 | impl DebugContext<'_> { | 15 | impl 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 | { |