aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty')
-rw-r--r--crates/hir_ty/Cargo.toml6
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check/case_conv.rs6
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs15
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs8
-rw-r--r--crates/hir_ty/src/display.rs149
-rw-r--r--crates/hir_ty/src/infer.rs8
-rw-r--r--crates/hir_ty/src/infer/expr.rs2
-rw-r--r--crates/hir_ty/src/infer/unify.rs37
-rw-r--r--crates/hir_ty/src/lib.rs3
-rw-r--r--crates/hir_ty/src/method_resolution.rs13
-rw-r--r--crates/hir_ty/src/test_db.rs6
-rw-r--r--crates/hir_ty/src/tests.rs8
-rw-r--r--crates/hir_ty/src/traits/chalk.rs23
-rw-r--r--crates/hir_ty/src/traits/chalk/interner.rs37
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs362
-rw-r--r--crates/hir_ty/src/traits/chalk/tls.rs162
16 files changed, 390 insertions, 455 deletions
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index 367a1b98d..fdc65a5c3 100644
--- a/crates/hir_ty/Cargo.toml
+++ b/crates/hir_ty/Cargo.toml
@@ -17,9 +17,9 @@ ena = "0.14.0"
17log = "0.4.8" 17log = "0.4.8"
18rustc-hash = "1.1.0" 18rustc-hash = "1.1.0"
19scoped-tls = "1" 19scoped-tls = "1"
20chalk-solve = { version = "0.34", default-features = false } 20chalk-solve = { version = "0.37", default-features = false }
21chalk-ir = "0.34" 21chalk-ir = "0.37"
22chalk-recursive = "0.34" 22chalk-recursive = "0.37"
23 23
24stdx = { path = "../stdx", version = "0.0.0" } 24stdx = { path = "../stdx", version = "0.0.0" }
25hir_def = { path = "../hir_def", version = "0.0.0" } 25hir_def = { path = "../hir_def", version = "0.0.0" }
diff --git a/crates/hir_ty/src/diagnostics/decl_check/case_conv.rs b/crates/hir_ty/src/diagnostics/decl_check/case_conv.rs
index b0144a289..14e4d92f0 100644
--- a/crates/hir_ty/src/diagnostics/decl_check/case_conv.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check/case_conv.rs
@@ -6,7 +6,7 @@
6 6
7/// Converts an identifier to an UpperCamelCase form. 7/// Converts an identifier to an UpperCamelCase form.
8/// Returns `None` if the string is already is UpperCamelCase. 8/// Returns `None` if the string is already is UpperCamelCase.
9pub fn to_camel_case(ident: &str) -> Option<String> { 9pub(crate) fn to_camel_case(ident: &str) -> Option<String> {
10 if is_camel_case(ident) { 10 if is_camel_case(ident) {
11 return None; 11 return None;
12 } 12 }
@@ -59,7 +59,7 @@ pub fn to_camel_case(ident: &str) -> Option<String> {
59 59
60/// Converts an identifier to a lower_snake_case form. 60/// Converts an identifier to a lower_snake_case form.
61/// Returns `None` if the string is already in lower_snake_case. 61/// Returns `None` if the string is already in lower_snake_case.
62pub fn to_lower_snake_case(ident: &str) -> Option<String> { 62pub(crate) fn to_lower_snake_case(ident: &str) -> Option<String> {
63 if is_lower_snake_case(ident) { 63 if is_lower_snake_case(ident) {
64 return None; 64 return None;
65 } else if is_upper_snake_case(ident) { 65 } else if is_upper_snake_case(ident) {
@@ -71,7 +71,7 @@ pub fn to_lower_snake_case(ident: &str) -> Option<String> {
71 71
72/// Converts an identifier to an UPPER_SNAKE_CASE form. 72/// Converts an identifier to an UPPER_SNAKE_CASE form.
73/// Returns `None` if the string is already is UPPER_SNAKE_CASE. 73/// Returns `None` if the string is already is UPPER_SNAKE_CASE.
74pub fn to_upper_snake_case(ident: &str) -> Option<String> { 74pub(crate) fn to_upper_snake_case(ident: &str) -> Option<String> {
75 if is_upper_snake_case(ident) { 75 if is_upper_snake_case(ident) {
76 return None; 76 return None;
77 } else if is_lower_snake_case(ident) { 77 } else if is_lower_snake_case(ident) {
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index 278a4b947..434b19354 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -17,17 +17,10 @@ use crate::{
17 ApplicationTy, InferenceResult, Ty, TypeCtor, 17 ApplicationTy, InferenceResult, Ty, TypeCtor,
18}; 18};
19 19
20pub use hir_def::{ 20pub(crate) use hir_def::{
21 body::{ 21 body::{Body, BodySourceMap},
22 scope::{ExprScopes, ScopeEntry, ScopeId}, 22 expr::{Expr, ExprId, MatchArm, Pat, PatId},
23 Body, BodySourceMap, ExprPtr, ExprSource, PatPtr, PatSource, 23 LocalFieldId, VariantId,
24 },
25 expr::{
26 ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp,
27 MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, UnaryOp,
28 },
29 src::HasSource,
30 LocalFieldId, Lookup, VariantId,
31}; 24};
32 25
33pub(super) struct ExprValidator<'a, 'b: 'a> { 26pub(super) struct ExprValidator<'a, 'b: 'a> {
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs
index 2da9688ca..6dc862826 100644
--- a/crates/hir_ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs
@@ -59,12 +59,12 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> {
59 } 59 }
60} 60}
61 61
62pub struct UnsafeExpr { 62pub(crate) struct UnsafeExpr {
63 pub expr: ExprId, 63 pub(crate) expr: ExprId,
64 pub inside_unsafe_block: bool, 64 pub(crate) inside_unsafe_block: bool,
65} 65}
66 66
67pub fn unsafe_expressions( 67pub(crate) fn unsafe_expressions(
68 db: &dyn HirDatabase, 68 db: &dyn HirDatabase,
69 infer: &InferenceResult, 69 infer: &InferenceResult,
70 def: DefWithBodyId, 70 def: DefWithBodyId,
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index d2e151f25..14e8c0633 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -26,6 +26,20 @@ pub trait HirDisplay {
26 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError>; 26 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError>;
27 27
28 /// Returns a `Display`able type that is human-readable. 28 /// Returns a `Display`able type that is human-readable.
29 fn into_displayable<'a>(
30 &'a self,
31 db: &'a dyn HirDatabase,
32 max_size: Option<usize>,
33 omit_verbose_types: bool,
34 display_target: DisplayTarget,
35 ) -> HirDisplayWrapper<'a, Self>
36 where
37 Self: Sized,
38 {
39 HirDisplayWrapper { db, t: self, max_size, omit_verbose_types, display_target }
40 }
41
42 /// Returns a `Display`able type that is human-readable.
29 /// Use this for showing types to the user (e.g. diagnostics) 43 /// Use this for showing types to the user (e.g. diagnostics)
30 fn display<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self> 44 fn display<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self>
31 where 45 where
@@ -82,6 +96,20 @@ pub trait HirDisplay {
82 }; 96 };
83 Ok(result) 97 Ok(result)
84 } 98 }
99
100 /// Returns a String representation of `self` for test purposes
101 fn display_test<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self>
102 where
103 Self: Sized,
104 {
105 HirDisplayWrapper {
106 db,
107 t: self,
108 max_size: None,
109 omit_verbose_types: false,
110 display_target: DisplayTarget::Test,
111 }
112 }
85} 113}
86 114
87impl<'a> HirFormatter<'a> { 115impl<'a> HirFormatter<'a> {
@@ -126,7 +154,7 @@ impl<'a> HirFormatter<'a> {
126} 154}
127 155
128#[derive(Clone, Copy)] 156#[derive(Clone, Copy)]
129enum DisplayTarget { 157pub enum DisplayTarget {
130 /// Display types for inlays, doc popups, autocompletion, etc... 158 /// Display types for inlays, doc popups, autocompletion, etc...
131 /// Showing `{unknown}` or not qualifying paths is fine here. 159 /// Showing `{unknown}` or not qualifying paths is fine here.
132 /// There's no reason for this to fail. 160 /// There's no reason for this to fail.
@@ -134,12 +162,17 @@ enum DisplayTarget {
134 /// Display types for inserting them in source files. 162 /// Display types for inserting them in source files.
135 /// The generated code should compile, so paths need to be qualified. 163 /// The generated code should compile, so paths need to be qualified.
136 SourceCode { module_id: ModuleId }, 164 SourceCode { module_id: ModuleId },
165 /// Only for test purpose to keep real types
166 Test,
137} 167}
138 168
139impl DisplayTarget { 169impl DisplayTarget {
140 fn is_source_code(&self) -> bool { 170 fn is_source_code(&self) -> bool {
141 matches!(self, Self::SourceCode {..}) 171 matches!(self, Self::SourceCode {..})
142 } 172 }
173 fn is_test(&self) -> bool {
174 matches!(self, Self::Test)
175 }
143} 176}
144 177
145#[derive(Debug)] 178#[derive(Debug)]
@@ -213,32 +246,32 @@ impl HirDisplay for ApplicationTy {
213 TypeCtor::Str => write!(f, "str")?, 246 TypeCtor::Str => write!(f, "str")?,
214 TypeCtor::Slice => { 247 TypeCtor::Slice => {
215 let t = self.parameters.as_single(); 248 let t = self.parameters.as_single();
216 write!(f, "[{}]", t.display(f.db))?; 249 write!(f, "[")?;
250 t.hir_fmt(f)?;
251 write!(f, "]")?;
217 } 252 }
218 TypeCtor::Array => { 253 TypeCtor::Array => {
219 let t = self.parameters.as_single(); 254 let t = self.parameters.as_single();
220 write!(f, "[{}; _]", t.display(f.db))?; 255 write!(f, "[")?;
256 t.hir_fmt(f)?;
257 write!(f, "; _]")?;
221 } 258 }
222 TypeCtor::RawPtr(m) => { 259 TypeCtor::RawPtr(m) => {
223 let t = self.parameters.as_single(); 260 let t = self.parameters.as_single();
224 let ty_display = t.display(f.db);
225 261
226 write!(f, "*{}", m.as_keyword_for_ptr())?; 262 write!(f, "*{}", m.as_keyword_for_ptr())?;
227 if matches!(t, Ty::Dyn(predicates) if predicates.len() > 1) { 263 if matches!(t, Ty::Dyn(predicates) if predicates.len() > 1) {
228 write!(f, "(")?; 264 write!(f, "(")?;
229 write!(f, "{}", ty_display)?; 265 t.hir_fmt(f)?;
230 write!(f, ")")?; 266 write!(f, ")")?;
231 } else { 267 } else {
232 write!(f, "{}", ty_display)?; 268 t.hir_fmt(f)?;
233 } 269 }
234 } 270 }
235 TypeCtor::Ref(m) => { 271 TypeCtor::Ref(m) => {
236 let t = self.parameters.as_single(); 272 let t = self.parameters.as_single();
237 let ty_display = if f.omit_verbose_types() { 273 let ty_display =
238 t.display_truncated(f.db, f.max_size) 274 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
239 } else {
240 t.display(f.db)
241 };
242 275
243 write!(f, "&{}", m.as_keyword_for_ref())?; 276 write!(f, "&{}", m.as_keyword_for_ref())?;
244 if matches!(t, Ty::Dyn(predicates) if predicates.len() > 1) { 277 if matches!(t, Ty::Dyn(predicates) if predicates.len() > 1) {
@@ -253,7 +286,9 @@ impl HirDisplay for ApplicationTy {
253 TypeCtor::Tuple { .. } => { 286 TypeCtor::Tuple { .. } => {
254 let ts = &self.parameters; 287 let ts = &self.parameters;
255 if ts.len() == 1 { 288 if ts.len() == 1 {
256 write!(f, "({},)", ts[0].display(f.db))?; 289 write!(f, "(")?;
290 ts[0].hir_fmt(f)?;
291 write!(f, ",)")?;
257 } else { 292 } else {
258 write!(f, "(")?; 293 write!(f, "(")?;
259 f.write_joined(&*ts.0, ", ")?; 294 f.write_joined(&*ts.0, ", ")?;
@@ -274,11 +309,12 @@ impl HirDisplay for ApplicationTy {
274 write!(f, ")")?; 309 write!(f, ")")?;
275 let ret = sig.ret(); 310 let ret = sig.ret();
276 if *ret != Ty::unit() { 311 if *ret != Ty::unit() {
277 let ret_display = if f.omit_verbose_types() { 312 let ret_display = ret.into_displayable(
278 ret.display_truncated(f.db, f.max_size) 313 f.db,
279 } else { 314 f.max_size,
280 ret.display(f.db) 315 f.omit_verbose_types,
281 }; 316 f.display_target,
317 );
282 write!(f, " -> {}", ret_display)?; 318 write!(f, " -> {}", ret_display)?;
283 } 319 }
284 } 320 }
@@ -310,17 +346,19 @@ impl HirDisplay for ApplicationTy {
310 write!(f, ")")?; 346 write!(f, ")")?;
311 let ret = sig.ret(); 347 let ret = sig.ret();
312 if *ret != Ty::unit() { 348 if *ret != Ty::unit() {
313 let ret_display = if f.omit_verbose_types() { 349 let ret_display = ret.into_displayable(
314 ret.display_truncated(f.db, f.max_size) 350 f.db,
315 } else { 351 f.max_size,
316 ret.display(f.db) 352 f.omit_verbose_types,
317 }; 353 f.display_target,
354 );
355
318 write!(f, " -> {}", ret_display)?; 356 write!(f, " -> {}", ret_display)?;
319 } 357 }
320 } 358 }
321 TypeCtor::Adt(def_id) => { 359 TypeCtor::Adt(def_id) => {
322 match f.display_target { 360 match f.display_target {
323 DisplayTarget::Diagnostics => { 361 DisplayTarget::Diagnostics | DisplayTarget::Test => {
324 let name = match def_id { 362 let name = match def_id {
325 AdtId::StructId(it) => f.db.struct_data(it).name.clone(), 363 AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
326 AdtId::UnionId(it) => f.db.union_data(it).name.clone(), 364 AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
@@ -389,12 +427,23 @@ impl HirDisplay for ApplicationTy {
389 _ => panic!("not an associated type"), 427 _ => panic!("not an associated type"),
390 }; 428 };
391 let trait_ = f.db.trait_data(trait_); 429 let trait_ = f.db.trait_data(trait_);
392 let type_alias = f.db.type_alias_data(type_alias); 430 let type_alias_data = f.db.type_alias_data(type_alias);
393 write!(f, "{}::{}", trait_.name, type_alias.name)?; 431
394 if self.parameters.len() > 0 { 432 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
395 write!(f, "<")?; 433 if f.display_target.is_test() {
396 f.write_joined(&*self.parameters.0, ", ")?; 434 write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
397 write!(f, ">")?; 435 if self.parameters.len() > 0 {
436 write!(f, "<")?;
437 f.write_joined(&*self.parameters.0, ", ")?;
438 write!(f, ">")?;
439 }
440 } else {
441 let projection_ty = ProjectionTy {
442 associated_ty: type_alias,
443 parameters: self.parameters.clone(),
444 };
445
446 projection_ty.hir_fmt(f)?;
398 } 447 }
399 } 448 }
400 TypeCtor::ForeignType(type_alias) => { 449 TypeCtor::ForeignType(type_alias) => {
@@ -439,11 +488,12 @@ impl HirDisplay for ApplicationTy {
439 write!(f, "|")?; 488 write!(f, "|")?;
440 }; 489 };
441 490
442 let ret_display = if f.omit_verbose_types() { 491 let ret_display = sig.ret().into_displayable(
443 sig.ret().display_truncated(f.db, f.max_size) 492 f.db,
444 } else { 493 f.max_size,
445 sig.ret().display(f.db) 494 f.omit_verbose_types,
446 }; 495 f.display_target,
496 );
447 write!(f, " -> {}", ret_display)?; 497 write!(f, " -> {}", ret_display)?;
448 } else { 498 } else {
449 write!(f, "{{closure}}")?; 499 write!(f, "{{closure}}")?;
@@ -461,7 +511,13 @@ impl HirDisplay for ProjectionTy {
461 } 511 }
462 512
463 let trait_ = f.db.trait_data(self.trait_(f.db)); 513 let trait_ = f.db.trait_data(self.trait_(f.db));
464 write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_.name)?; 514 let first_parameter = self.parameters[0].into_displayable(
515 f.db,
516 f.max_size,
517 f.omit_verbose_types,
518 f.display_target,
519 );
520 write!(f, "<{} as {}", first_parameter, trait_.name)?;
465 if self.parameters.len() > 1 { 521 if self.parameters.len() > 1 {
466 write!(f, "<")?; 522 write!(f, "<")?;
467 f.write_joined(&self.parameters[1..], ", ")?; 523 f.write_joined(&self.parameters[1..], ", ")?;
@@ -640,10 +696,10 @@ impl HirDisplay for GenericPredicate {
640 projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?; 696 projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?;
641 write!( 697 write!(
642 f, 698 f,
643 ">::{} = {}", 699 ">::{} = ",
644 f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name, 700 f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name,
645 projection_pred.ty.display(f.db)
646 )?; 701 )?;
702 projection_pred.ty.hir_fmt(f)?;
647 } 703 }
648 GenericPredicate::Error => write!(f, "{{error}}")?, 704 GenericPredicate::Error => write!(f, "{{error}}")?,
649 } 705 }
@@ -654,13 +710,18 @@ impl HirDisplay for GenericPredicate {
654impl HirDisplay for Obligation { 710impl HirDisplay for Obligation {
655 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 711 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
656 match self { 712 match self {
657 Obligation::Trait(tr) => write!(f, "Implements({})", tr.display(f.db)), 713 Obligation::Trait(tr) => {
658 Obligation::Projection(proj) => write!( 714 write!(f, "Implements(")?;
659 f, 715 tr.hir_fmt(f)?;
660 "Normalize({} => {})", 716 write!(f, ")")
661 proj.projection_ty.display(f.db), 717 }
662 proj.ty.display(f.db) 718 Obligation::Projection(proj) => {
663 ), 719 write!(f, "Normalize(")?;
720 proj.projection_ty.hir_fmt(f)?;
721 write!(f, " => ")?;
722 proj.ty.hir_fmt(f)?;
723 write!(f, ")")
724 }
664 } 725 }
665 } 726 }
666} 727}
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 644ebd42d..a14d67c06 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -94,7 +94,7 @@ enum BindingMode {
94} 94}
95 95
96impl BindingMode { 96impl BindingMode {
97 pub fn convert(annotation: BindingAnnotation) -> BindingMode { 97 fn convert(annotation: BindingAnnotation) -> BindingMode {
98 match annotation { 98 match annotation {
99 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move, 99 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move,
100 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Shared), 100 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Shared),
@@ -214,9 +214,9 @@ struct InferenceContext<'a> {
214 214
215#[derive(Clone, Debug)] 215#[derive(Clone, Debug)]
216struct BreakableContext { 216struct BreakableContext {
217 pub may_break: bool, 217 may_break: bool,
218 pub break_ty: Ty, 218 break_ty: Ty,
219 pub label: Option<name::Name>, 219 label: Option<name::Name>,
220} 220}
221 221
222fn find_breakable<'c>( 222fn find_breakable<'c>(
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 8ac4cf89a..605951b10 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -107,7 +107,7 @@ impl<'a> InferenceContext<'a> {
107 } 107 }
108 } 108 }
109 109
110 pub fn callable_sig(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> { 110 pub(crate) fn callable_sig(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> {
111 match ty.callable_sig(self.db) { 111 match ty.callable_sig(self.db) {
112 Some(sig) => Some((sig.params().to_vec(), sig.ret().clone())), 112 Some(sig) => Some((sig.params().to_vec(), sig.ret().clone())),
113 None => self.callable_sig_from_fn_trait(ty, num_args), 113 None => self.callable_sig_from_fn_trait(ty, num_args),
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 2e895d911..76984242e 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -35,7 +35,7 @@ where
35 35
36#[derive(Debug)] 36#[derive(Debug)]
37pub(super) struct Canonicalized<T> { 37pub(super) struct Canonicalized<T> {
38 pub value: Canonical<T>, 38 pub(super) value: Canonical<T>,
39 free_vars: Vec<InferTy>, 39 free_vars: Vec<InferTy>,
40} 40}
41 41
@@ -127,7 +127,7 @@ where
127} 127}
128 128
129impl<T> Canonicalized<T> { 129impl<T> Canonicalized<T> {
130 pub fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { 130 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty {
131 ty.walk_mut_binders( 131 ty.walk_mut_binders(
132 &mut |ty, binders| { 132 &mut |ty, binders| {
133 if let &mut Ty::Bound(bound) = ty { 133 if let &mut Ty::Bound(bound) = ty {
@@ -141,7 +141,11 @@ impl<T> Canonicalized<T> {
141 ty 141 ty
142 } 142 }
143 143
144 pub fn apply_solution(&self, ctx: &mut InferenceContext<'_>, solution: Canonical<Substs>) { 144 pub(super) fn apply_solution(
145 &self,
146 ctx: &mut InferenceContext<'_>,
147 solution: Canonical<Substs>,
148 ) {
145 // the solution may contain new variables, which we need to convert to new inference vars 149 // the solution may contain new variables, which we need to convert to new inference vars
146 let new_vars = Substs( 150 let new_vars = Substs(
147 solution 151 solution
@@ -164,7 +168,7 @@ impl<T> Canonicalized<T> {
164 } 168 }
165} 169}
166 170
167pub fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> { 171pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> {
168 let mut table = InferenceTable::new(); 172 let mut table = InferenceTable::new();
169 let vars = Substs( 173 let vars = Substs(
170 tys.kinds 174 tys.kinds
@@ -199,41 +203,46 @@ pub(crate) struct InferenceTable {
199} 203}
200 204
201impl InferenceTable { 205impl InferenceTable {
202 pub fn new() -> Self { 206 pub(crate) fn new() -> Self {
203 InferenceTable { var_unification_table: InPlaceUnificationTable::new() } 207 InferenceTable { var_unification_table: InPlaceUnificationTable::new() }
204 } 208 }
205 209
206 pub fn new_type_var(&mut self) -> Ty { 210 pub(crate) fn new_type_var(&mut self) -> Ty {
207 Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 211 Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown)))
208 } 212 }
209 213
210 pub fn new_integer_var(&mut self) -> Ty { 214 pub(crate) fn new_integer_var(&mut self) -> Ty {
211 Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 215 Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown)))
212 } 216 }
213 217
214 pub fn new_float_var(&mut self) -> Ty { 218 pub(crate) fn new_float_var(&mut self) -> Ty {
215 Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 219 Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown)))
216 } 220 }
217 221
218 pub fn new_maybe_never_type_var(&mut self) -> Ty { 222 pub(crate) fn new_maybe_never_type_var(&mut self) -> Ty {
219 Ty::Infer(InferTy::MaybeNeverTypeVar( 223 Ty::Infer(InferTy::MaybeNeverTypeVar(
220 self.var_unification_table.new_key(TypeVarValue::Unknown), 224 self.var_unification_table.new_key(TypeVarValue::Unknown),
221 )) 225 ))
222 } 226 }
223 227
224 pub fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { 228 pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty {
225 self.resolve_ty_completely_inner(&mut Vec::new(), ty) 229 self.resolve_ty_completely_inner(&mut Vec::new(), ty)
226 } 230 }
227 231
228 pub fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty { 232 pub(crate) fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty {
229 self.resolve_ty_as_possible_inner(&mut Vec::new(), ty) 233 self.resolve_ty_as_possible_inner(&mut Vec::new(), ty)
230 } 234 }
231 235
232 pub fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 236 pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
233 self.unify_inner(ty1, ty2, 0) 237 self.unify_inner(ty1, ty2, 0)
234 } 238 }
235 239
236 pub fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs, depth: usize) -> bool { 240 pub(crate) fn unify_substs(
241 &mut self,
242 substs1: &Substs,
243 substs2: &Substs,
244 depth: usize,
245 ) -> bool {
237 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) 246 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth))
238 } 247 }
239 248
@@ -331,7 +340,7 @@ impl InferenceTable {
331 340
332 /// If `ty` is a type variable with known type, returns that type; 341 /// If `ty` is a type variable with known type, returns that type;
333 /// otherwise, return ty. 342 /// otherwise, return ty.
334 pub fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { 343 pub(crate) fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> {
335 let mut ty = Cow::Borrowed(ty); 344 let mut ty = Cow::Borrowed(ty);
336 // The type variable could resolve to a int/float variable. Hence try 345 // The type variable could resolve to a int/float variable. Hence try
337 // resolving up to three times; each type of variable shouldn't occur 346 // resolving up to three times; each type of variable shouldn't occur
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 768d95eff..5a8c97198 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -1,6 +1,5 @@
1//! The type system. We currently use this to infer types for completion, hover 1//! The type system. We currently use this to infer types for completion, hover
2//! information and various assists. 2//! information and various assists.
3
4#[allow(unused)] 3#[allow(unused)]
5macro_rules! eprintln { 4macro_rules! eprintln {
6 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) }; 5 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
@@ -1115,5 +1114,5 @@ pub struct ReturnTypeImplTraits {
1115 1114
1116#[derive(Clone, PartialEq, Eq, Debug, Hash)] 1115#[derive(Clone, PartialEq, Eq, Debug, Hash)]
1117pub(crate) struct ReturnTypeImplTrait { 1116pub(crate) struct ReturnTypeImplTrait {
1118 pub bounds: Binders<Vec<GenericPredicate>>, 1117 pub(crate) bounds: Binders<Vec<GenericPredicate>>,
1119} 1118}
diff --git a/crates/hir_ty/src/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
743pub 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.
745fn generic_implements_goal( 758fn 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)]
24pub struct TestDB { 24pub(crate) struct TestDB {
25 storage: salsa::Storage<TestDB>, 25 storage: salsa::Storage<TestDB>,
26 events: Mutex<Option<Vec<salsa::Event>>>, 26 events: Mutex<Option<Vec<salsa::Event>>>,
27} 27}
@@ -113,13 +113,13 @@ impl TestDB {
113} 113}
114 114
115impl TestDB { 115impl TestDB {
116 pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event> { 116 pub(crate) fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event> {
117 *self.events.lock().unwrap() = Some(Vec::new()); 117 *self.events.lock().unwrap() = Some(Vec::new());
118 f(); 118 f();
119 self.events.lock().unwrap().take().unwrap() 119 self.events.lock().unwrap().take().unwrap()
120 } 120 }
121 121
122 pub fn log_executed(&self, f: impl FnOnce()) -> Vec<String> { 122 pub(crate) fn log_executed(&self, f: impl FnOnce()) -> Vec<String> {
123 let events = self.log(f); 123 let events = self.log(f);
124 events 124 events
125 .into_iter() 125 .into_iter()
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs
index 0445efc9e..104ef334c 100644
--- a/crates/hir_ty/src/tests.rs
+++ b/crates/hir_ty/src/tests.rs
@@ -74,7 +74,7 @@ fn check_types_impl(ra_fixture: &str, display_source: bool) {
74 let module = db.module_for_file(file_id); 74 let module = db.module_for_file(file_id);
75 ty.display_source_code(&db, module).unwrap() 75 ty.display_source_code(&db, module).unwrap()
76 } else { 76 } else {
77 ty.display(&db).to_string() 77 ty.display_test(&db).to_string()
78 }; 78 };
79 assert_eq!(expected, actual); 79 assert_eq!(expected, actual);
80 checked_one = true; 80 checked_one = true;
@@ -163,7 +163,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
163 macro_prefix, 163 macro_prefix,
164 range, 164 range,
165 ellipsize(text, 15), 165 ellipsize(text, 15),
166 ty.display(&db) 166 ty.display_test(&db)
167 ); 167 );
168 } 168 }
169 if include_mismatches { 169 if include_mismatches {
@@ -179,8 +179,8 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
179 "{}{:?}: expected {}, got {}\n", 179 "{}{:?}: expected {}, got {}\n",
180 macro_prefix, 180 macro_prefix,
181 range, 181 range,
182 mismatch.expected.display(&db), 182 mismatch.expected.display_test(&db),
183 mismatch.actual.display(&db), 183 mismatch.actual.display_test(&db),
184 ); 184 );
185 } 185 }
186 } 186 }
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index cbe5cd7dd..55e2c3a3e 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -3,7 +3,7 @@ use std::sync::Arc;
3 3
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg, TypeName}; 6use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg};
7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; 7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
8 8
9use base_db::{salsa::InternKey, CrateId}; 9use base_db::{salsa::InternKey, CrateId};
@@ -27,7 +27,7 @@ use mapping::{
27 TypeAliasAsValue, 27 TypeAliasAsValue,
28}; 28};
29 29
30pub use self::interner::*; 30pub(crate) use self::interner::*;
31 31
32pub(super) mod tls; 32pub(super) mod tls;
33mod interner; 33mod interner;
@@ -81,7 +81,10 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
81 81
82 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone()); 82 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone());
83 83
84 fn binder_kind(ty: &Ty, binders: &CanonicalVarKinds<Interner>) -> Option<chalk_ir::TyKind> { 84 fn binder_kind(
85 ty: &Ty,
86 binders: &CanonicalVarKinds<Interner>,
87 ) -> Option<chalk_ir::TyVariableKind> {
85 if let Ty::Bound(bv) = ty { 88 if let Ty::Bound(bv) = ty {
86 let binders = binders.as_slice(&Interner); 89 let binders = binders.as_slice(&Interner);
87 if bv.debruijn == DebruijnIndex::INNERMOST { 90 if bv.debruijn == DebruijnIndex::INNERMOST {
@@ -95,8 +98,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
95 98
96 let self_ty_fp = TyFingerprint::for_impl(&ty); 99 let self_ty_fp = TyFingerprint::for_impl(&ty);
97 let fps: &[TyFingerprint] = match binder_kind(&ty, binders) { 100 let fps: &[TyFingerprint] = match binder_kind(&ty, binders) {
98 Some(chalk_ir::TyKind::Integer) => &ALL_INT_FPS, 101 Some(chalk_ir::TyVariableKind::Integer) => &ALL_INT_FPS,
99 Some(chalk_ir::TyKind::Float) => &ALL_FLOAT_FPS, 102 Some(chalk_ir::TyVariableKind::Float) => &ALL_FLOAT_FPS,
100 _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]), 103 _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]),
101 }; 104 };
102 105
@@ -129,12 +132,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
129 debug!("impls_for_trait returned {} impls", result.len()); 132 debug!("impls_for_trait returned {} impls", result.len());
130 result 133 result
131 } 134 }
132 fn impl_provided_for( 135 fn impl_provided_for(&self, auto_trait_id: TraitId, kind: &chalk_ir::TyKind<Interner>) -> bool {
133 &self, 136 debug!("impl_provided_for {:?}, {:?}", auto_trait_id, kind);
134 auto_trait_id: TraitId,
135 application_ty: &chalk_ir::ApplicationTy<Interner>,
136 ) -> bool {
137 debug!("impl_provided_for {:?}, {:?}", auto_trait_id, application_ty);
138 false // FIXME 137 false // FIXME
139 } 138 }
140 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> { 139 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> {
@@ -466,7 +465,7 @@ pub(crate) fn struct_datum_query(
466 struct_id: AdtId, 465 struct_id: AdtId,
467) -> Arc<StructDatum> { 466) -> Arc<StructDatum> {
468 debug!("struct_datum {:?}", struct_id); 467 debug!("struct_datum {:?}", struct_id);
469 let type_ctor: TypeCtor = from_chalk(db, TypeName::Adt(struct_id)); 468 let type_ctor = TypeCtor::Adt(from_chalk(db, struct_id));
470 debug!("struct {:?} = {:?}", struct_id, type_ctor); 469 debug!("struct {:?} = {:?}", struct_id, type_ctor);
471 let num_params = type_ctor.num_ty_params(db); 470 let num_params = type_ctor.num_ty_params(db);
472 let upstream = type_ctor.krate(db) != Some(krate); 471 let upstream = type_ctor.krate(db) != Some(krate);
diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/traits/chalk/interner.rs
index f9304b7d0..39569e690 100644
--- a/crates/hir_ty/src/traits/chalk/interner.rs
+++ b/crates/hir_ty/src/traits/chalk/interner.rs
@@ -10,21 +10,21 @@ use std::{fmt, sync::Arc};
10#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] 10#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
11pub struct Interner; 11pub struct Interner;
12 12
13pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>; 13pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
14pub type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; 14pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>;
15pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>; 15pub(crate) type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
16pub type TraitId = chalk_ir::TraitId<Interner>; 16pub(crate) type TraitId = chalk_ir::TraitId<Interner>;
17pub type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>; 17pub(crate) type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>;
18pub type AdtId = chalk_ir::AdtId<Interner>; 18pub(crate) type AdtId = chalk_ir::AdtId<Interner>;
19pub type StructDatum = chalk_solve::rust_ir::AdtDatum<Interner>; 19pub(crate) type StructDatum = chalk_solve::rust_ir::AdtDatum<Interner>;
20pub type ImplId = chalk_ir::ImplId<Interner>; 20pub(crate) type ImplId = chalk_ir::ImplId<Interner>;
21pub type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>; 21pub(crate) type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>;
22pub type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>; 22pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>;
23pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; 23pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>;
24pub type FnDefId = chalk_ir::FnDefId<Interner>; 24pub(crate) type FnDefId = chalk_ir::FnDefId<Interner>;
25pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; 25pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>;
26pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 26pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
27pub type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; 27pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>;
28 28
29impl chalk_ir::interner::Interner for Interner { 29impl chalk_ir::interner::Interner for Interner {
30 type InternedType = Arc<chalk_ir::TyData<Self>>; 30 type InternedType = Arc<chalk_ir::TyData<Self>>;
@@ -122,13 +122,6 @@ impl chalk_ir::interner::Interner for Interner {
122 tls::with_current_program(|prog| Some(prog?.debug_program_clause_implication(pci, fmt))) 122 tls::with_current_program(|prog| Some(prog?.debug_program_clause_implication(pci, fmt)))
123 } 123 }
124 124
125 fn debug_application_ty(
126 application_ty: &chalk_ir::ApplicationTy<Interner>,
127 fmt: &mut fmt::Formatter<'_>,
128 ) -> Option<fmt::Result> {
129 tls::with_current_program(|prog| Some(prog?.debug_application_ty(application_ty, fmt)))
130 }
131
132 fn debug_substitution( 125 fn debug_substitution(
133 substitution: &chalk_ir::Substitution<Interner>, 126 substitution: &chalk_ir::Substitution<Interner>,
134 fmt: &mut fmt::Formatter<'_>, 127 fmt: &mut fmt::Formatter<'_>,
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index dd7affcec..86cbc4c7e 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -5,7 +5,7 @@
5 5
6use chalk_ir::{ 6use chalk_ir::{
7 cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, Scalar, 7 cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, Scalar,
8 TypeName, UniverseIndex, 8 UniverseIndex,
9}; 9};
10use chalk_solve::rust_ir; 10use chalk_solve::rust_ir;
11 11
@@ -32,7 +32,7 @@ impl ToChalk for Ty {
32 TypeCtor::Array => array_to_chalk(db, apply_ty.parameters), 32 TypeCtor::Array => array_to_chalk(db, apply_ty.parameters),
33 TypeCtor::FnPtr { num_args: _, is_varargs } => { 33 TypeCtor::FnPtr { num_args: _, is_varargs } => {
34 let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); 34 let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner);
35 chalk_ir::TyData::Function(chalk_ir::FnPointer { 35 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
36 num_binders: 0, 36 num_binders: 0,
37 sig: chalk_ir::FnSig { 37 sig: chalk_ir::FnSig {
38 abi: (), 38 abi: (),
@@ -43,10 +43,68 @@ impl ToChalk for Ty {
43 }) 43 })
44 .intern(&Interner) 44 .intern(&Interner)
45 } 45 }
46 _ => { 46 TypeCtor::AssociatedType(type_alias) => {
47 let name = apply_ty.ctor.to_chalk(db); 47 let assoc_type = TypeAliasAsAssocType(type_alias);
48 let assoc_type_id = assoc_type.to_chalk(db);
48 let substitution = apply_ty.parameters.to_chalk(db); 49 let substitution = apply_ty.parameters.to_chalk(db);
49 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) 50 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
51 }
52
53 TypeCtor::OpaqueType(impl_trait_id) => {
54 let id = impl_trait_id.to_chalk(db);
55 let substitution = apply_ty.parameters.to_chalk(db);
56 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner)
57 }
58
59 TypeCtor::ForeignType(type_alias) => {
60 let foreign_type = TypeAliasAsForeignType(type_alias);
61 let foreign_type_id = foreign_type.to_chalk(db);
62 chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner)
63 }
64
65 TypeCtor::Bool => chalk_ir::TyKind::Scalar(Scalar::Bool).intern(&Interner),
66 TypeCtor::Char => chalk_ir::TyKind::Scalar(Scalar::Char).intern(&Interner),
67 TypeCtor::Int(int_ty) => {
68 chalk_ir::TyKind::Scalar(int_ty_to_chalk(int_ty)).intern(&Interner)
69 }
70 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => {
71 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F32))
72 .intern(&Interner)
73 }
74 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => {
75 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F64))
76 .intern(&Interner)
77 }
78
79 TypeCtor::Tuple { cardinality } => {
80 let substitution = apply_ty.parameters.to_chalk(db);
81 chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner)
82 }
83 TypeCtor::RawPtr(mutability) => {
84 let ty = apply_ty.parameters[0].clone().to_chalk(db);
85 chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner)
86 }
87 TypeCtor::Slice => {
88 chalk_ir::TyKind::Slice(apply_ty.parameters[0].clone().to_chalk(db))
89 .intern(&Interner)
90 }
91 TypeCtor::Str => chalk_ir::TyKind::Str.intern(&Interner),
92 TypeCtor::FnDef(callable_def) => {
93 let id = callable_def.to_chalk(db);
94 let substitution = apply_ty.parameters.to_chalk(db);
95 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner)
96 }
97 TypeCtor::Never => chalk_ir::TyKind::Never.intern(&Interner),
98
99 TypeCtor::Closure { def, expr } => {
100 let closure_id = db.intern_closure((def, expr));
101 let substitution = apply_ty.parameters.to_chalk(db);
102 chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner)
103 }
104
105 TypeCtor::Adt(adt_id) => {
106 let substitution = apply_ty.parameters.to_chalk(db);
107 chalk_ir::TyKind::Adt(chalk_ir::AdtId(adt_id), substitution).intern(&Interner)
50 } 108 }
51 }, 109 },
52 Ty::Projection(proj_ty) => { 110 Ty::Projection(proj_ty) => {
@@ -67,7 +125,7 @@ impl ToChalk for Ty {
67 } 125 }
68 .to_ty::<Interner>(&Interner) 126 .to_ty::<Interner>(&Interner)
69 } 127 }
70 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner), 128 Ty::Bound(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner),
71 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 129 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
72 Ty::Dyn(predicates) => { 130 Ty::Dyn(predicates) => {
73 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( 131 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
@@ -78,55 +136,45 @@ impl ToChalk for Ty {
78 bounds: make_binders(where_clauses, 1), 136 bounds: make_binders(where_clauses, 1),
79 lifetime: LifetimeData::Static.intern(&Interner), 137 lifetime: LifetimeData::Static.intern(&Interner),
80 }; 138 };
81 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner) 139 chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner)
82 } 140 }
83 Ty::Opaque(opaque_ty) => { 141 Ty::Opaque(opaque_ty) => {
84 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db); 142 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db);
85 let substitution = opaque_ty.parameters.to_chalk(db); 143 let substitution = opaque_ty.parameters.to_chalk(db);
86 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { 144 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
87 opaque_ty_id, 145 opaque_ty_id,
88 substitution, 146 substitution,
89 })) 147 }))
90 .intern(&Interner) 148 .intern(&Interner)
91 } 149 }
92 Ty::Unknown => { 150 Ty::Unknown => chalk_ir::TyKind::Error.intern(&Interner),
93 let substitution = chalk_ir::Substitution::empty(&Interner);
94 let name = TypeName::Error;
95 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
96 }
97 } 151 }
98 } 152 }
99 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { 153 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
100 match chalk.data(&Interner).clone() { 154 match chalk.data(&Interner).kind.clone() {
101 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { 155 chalk_ir::TyKind::Error => Ty::Unknown,
102 TypeName::Error => Ty::Unknown, 156 chalk_ir::TyKind::Array(ty, _size) => {
103 TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution), 157 Ty::apply(TypeCtor::Array, Substs::single(from_chalk(db, ty)))
104 TypeName::Array => array_from_chalk(db, apply_ty.substitution), 158 }
105 _ => { 159 chalk_ir::TyKind::Placeholder(idx) => {
106 let ctor = from_chalk(db, apply_ty.name);
107 let parameters = from_chalk(db, apply_ty.substitution);
108 Ty::Apply(ApplicationTy { ctor, parameters })
109 }
110 },
111 chalk_ir::TyData::Placeholder(idx) => {
112 assert_eq!(idx.ui, UniverseIndex::ROOT); 160 assert_eq!(idx.ui, UniverseIndex::ROOT);
113 let interned_id = crate::db::GlobalTypeParamId::from_intern_id( 161 let interned_id = crate::db::GlobalTypeParamId::from_intern_id(
114 crate::salsa::InternId::from(idx.idx), 162 crate::salsa::InternId::from(idx.idx),
115 ); 163 );
116 Ty::Placeholder(db.lookup_intern_type_param_id(interned_id)) 164 Ty::Placeholder(db.lookup_intern_type_param_id(interned_id))
117 } 165 }
118 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Projection(proj)) => { 166 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => {
119 let associated_ty = 167 let associated_ty =
120 from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0; 168 from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0;
121 let parameters = from_chalk(db, proj.substitution); 169 let parameters = from_chalk(db, proj.substitution);
122 Ty::Projection(ProjectionTy { associated_ty, parameters }) 170 Ty::Projection(ProjectionTy { associated_ty, parameters })
123 } 171 }
124 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => { 172 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => {
125 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id); 173 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id);
126 let parameters = from_chalk(db, opaque_ty.substitution); 174 let parameters = from_chalk(db, opaque_ty.substitution);
127 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) 175 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })
128 } 176 }
129 chalk_ir::TyData::Function(chalk_ir::FnPointer { 177 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
130 num_binders, 178 num_binders,
131 sig: chalk_ir::FnSig { variadic, .. }, 179 sig: chalk_ir::FnSig { variadic, .. },
132 substitution, 180 substitution,
@@ -145,9 +193,9 @@ impl ToChalk for Ty {
145 parameters, 193 parameters,
146 }) 194 })
147 } 195 }
148 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx), 196 chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx),
149 chalk_ir::TyData::InferenceVar(_iv, _kind) => Ty::Unknown, 197 chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown,
150 chalk_ir::TyData::Dyn(where_clauses) => { 198 chalk_ir::TyKind::Dyn(where_clauses) => {
151 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); 199 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1);
152 let predicates = where_clauses 200 let predicates = where_clauses
153 .bounds 201 .bounds
@@ -157,10 +205,76 @@ impl ToChalk for Ty {
157 .collect(); 205 .collect();
158 Ty::Dyn(predicates) 206 Ty::Dyn(predicates)
159 } 207 }
208
209 chalk_ir::TyKind::Adt(struct_id, subst) => {
210 apply_ty_from_chalk(db, TypeCtor::Adt(struct_id.0), subst)
211 }
212 chalk_ir::TyKind::AssociatedType(type_id, subst) => apply_ty_from_chalk(
213 db,
214 TypeCtor::AssociatedType(from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0),
215 subst,
216 ),
217 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => {
218 apply_ty_from_chalk(db, TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)), subst)
219 }
220
221 chalk_ir::TyKind::Scalar(Scalar::Bool) => Ty::simple(TypeCtor::Bool),
222 chalk_ir::TyKind::Scalar(Scalar::Char) => Ty::simple(TypeCtor::Char),
223 chalk_ir::TyKind::Scalar(Scalar::Int(int_ty)) => Ty::simple(TypeCtor::Int(IntTy {
224 signedness: Signedness::Signed,
225 bitness: bitness_from_chalk_int(int_ty),
226 })),
227 chalk_ir::TyKind::Scalar(Scalar::Uint(uint_ty)) => Ty::simple(TypeCtor::Int(IntTy {
228 signedness: Signedness::Unsigned,
229 bitness: bitness_from_chalk_uint(uint_ty),
230 })),
231 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => {
232 Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }))
233 }
234 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => {
235 Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }))
236 }
237 chalk_ir::TyKind::Tuple(cardinality, subst) => {
238 apply_ty_from_chalk(db, TypeCtor::Tuple { cardinality: cardinality as u16 }, subst)
239 }
240 chalk_ir::TyKind::Raw(mutability, ty) => {
241 Ty::apply_one(TypeCtor::RawPtr(from_chalk(db, mutability)), from_chalk(db, ty))
242 }
243 chalk_ir::TyKind::Slice(ty) => Ty::apply_one(TypeCtor::Slice, from_chalk(db, ty)),
244 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => {
245 Ty::apply_one(TypeCtor::Ref(from_chalk(db, mutability)), from_chalk(db, ty))
246 }
247 chalk_ir::TyKind::Str => Ty::simple(TypeCtor::Str),
248 chalk_ir::TyKind::Never => Ty::simple(TypeCtor::Never),
249
250 chalk_ir::TyKind::FnDef(fn_def_id, subst) => {
251 let callable_def = from_chalk(db, fn_def_id);
252 apply_ty_from_chalk(db, TypeCtor::FnDef(callable_def), subst)
253 }
254
255 chalk_ir::TyKind::Closure(id, subst) => {
256 let id: crate::db::ClosureId = id.into();
257 let (def, expr) = db.lookup_intern_closure(id);
258 apply_ty_from_chalk(db, TypeCtor::Closure { def, expr }, subst)
259 }
260
261 chalk_ir::TyKind::Foreign(foreign_def_id) => Ty::simple(TypeCtor::ForeignType(
262 from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0,
263 )),
264 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME
265 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME
160 } 266 }
161 } 267 }
162} 268}
163 269
270fn apply_ty_from_chalk(
271 db: &dyn HirDatabase,
272 ctor: TypeCtor,
273 subst: chalk_ir::Substitution<Interner>,
274) -> Ty {
275 Ty::Apply(ApplicationTy { ctor, parameters: from_chalk(db, subst) })
276}
277
164/// We currently don't model lifetimes, but Chalk does. So, we have to insert a 278/// We currently don't model lifetimes, but Chalk does. So, we have to insert a
165/// fake lifetime here, because Chalks built-in logic may expect it to be there. 279/// fake lifetime here, because Chalks built-in logic may expect it to be there.
166fn ref_to_chalk( 280fn ref_to_chalk(
@@ -170,60 +284,21 @@ fn ref_to_chalk(
170) -> chalk_ir::Ty<Interner> { 284) -> chalk_ir::Ty<Interner> {
171 let arg = subst[0].clone().to_chalk(db); 285 let arg = subst[0].clone().to_chalk(db);
172 let lifetime = LifetimeData::Static.intern(&Interner); 286 let lifetime = LifetimeData::Static.intern(&Interner);
173 chalk_ir::ApplicationTy { 287 chalk_ir::TyKind::Ref(mutability.to_chalk(db), lifetime, arg).intern(&Interner)
174 name: TypeName::Ref(mutability.to_chalk(db)),
175 substitution: chalk_ir::Substitution::from_iter(
176 &Interner,
177 vec![lifetime.cast(&Interner), arg.cast(&Interner)],
178 ),
179 }
180 .intern(&Interner)
181}
182
183/// Here we remove the lifetime from the type we got from Chalk.
184fn ref_from_chalk(
185 db: &dyn HirDatabase,
186 mutability: chalk_ir::Mutability,
187 subst: chalk_ir::Substitution<Interner>,
188) -> Ty {
189 let tys = subst
190 .iter(&Interner)
191 .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone())))
192 .collect();
193 Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys))
194} 288}
195 289
196/// We currently don't model constants, but Chalk does. So, we have to insert a 290/// We currently don't model constants, but Chalk does. So, we have to insert a
197/// fake constant here, because Chalks built-in logic may expect it to be there. 291/// fake constant here, because Chalks built-in logic may expect it to be there.
198fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> { 292fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> {
199 let arg = subst[0].clone().to_chalk(db); 293 let arg = subst[0].clone().to_chalk(db);
200 let usize_ty = chalk_ir::ApplicationTy { 294 let usize_ty =
201 name: TypeName::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)), 295 chalk_ir::TyKind::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)).intern(&Interner);
202 substitution: chalk_ir::Substitution::empty(&Interner),
203 }
204 .intern(&Interner);
205 let const_ = chalk_ir::ConstData { 296 let const_ = chalk_ir::ConstData {
206 ty: usize_ty, 297 ty: usize_ty,
207 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }), 298 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }),
208 } 299 }
209 .intern(&Interner); 300 .intern(&Interner);
210 chalk_ir::ApplicationTy { 301 chalk_ir::TyKind::Array(arg, const_).intern(&Interner)
211 name: TypeName::Array,
212 substitution: chalk_ir::Substitution::from_iter(
213 &Interner,
214 vec![arg.cast(&Interner), const_.cast(&Interner)],
215 ),
216 }
217 .intern(&Interner)
218}
219
220/// Here we remove the const from the type we got from Chalk.
221fn array_from_chalk(db: &dyn HirDatabase, subst: chalk_ir::Substitution<Interner>) -> Ty {
222 let tys = subst
223 .iter(&Interner)
224 .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone())))
225 .collect();
226 Ty::apply(TypeCtor::Array, Substs(tys))
227} 302}
228 303
229impl ToChalk for Substs { 304impl ToChalk for Substs {
@@ -288,124 +363,6 @@ impl ToChalk for OpaqueTyId {
288 } 363 }
289} 364}
290 365
291impl ToChalk for TypeCtor {
292 type Chalk = TypeName<Interner>;
293
294 fn to_chalk(self, db: &dyn HirDatabase) -> TypeName<Interner> {
295 match self {
296 TypeCtor::AssociatedType(type_alias) => {
297 let assoc_type = TypeAliasAsAssocType(type_alias);
298 let assoc_type_id = assoc_type.to_chalk(db);
299 TypeName::AssociatedType(assoc_type_id)
300 }
301
302 TypeCtor::OpaqueType(impl_trait_id) => {
303 let id = impl_trait_id.to_chalk(db);
304 TypeName::OpaqueType(id)
305 }
306
307 TypeCtor::ForeignType(type_alias) => {
308 let foreign_type = TypeAliasAsForeignType(type_alias);
309 let foreign_type_id = foreign_type.to_chalk(db);
310 TypeName::Foreign(foreign_type_id)
311 }
312
313 TypeCtor::Bool => TypeName::Scalar(Scalar::Bool),
314 TypeCtor::Char => TypeName::Scalar(Scalar::Char),
315 TypeCtor::Int(int_ty) => TypeName::Scalar(int_ty_to_chalk(int_ty)),
316 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => {
317 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32))
318 }
319 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => {
320 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64))
321 }
322
323 TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()),
324 TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)),
325 TypeCtor::Slice => TypeName::Slice,
326 TypeCtor::Array => TypeName::Array,
327 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
328 TypeCtor::Str => TypeName::Str,
329 TypeCtor::FnDef(callable_def) => {
330 let id = callable_def.to_chalk(db);
331 TypeName::FnDef(id)
332 }
333 TypeCtor::Never => TypeName::Never,
334
335 TypeCtor::Closure { def, expr } => {
336 let closure_id = db.intern_closure((def, expr));
337 TypeName::Closure(closure_id.into())
338 }
339
340 TypeCtor::Adt(adt_id) => TypeName::Adt(chalk_ir::AdtId(adt_id)),
341
342 TypeCtor::FnPtr { .. } => {
343 // This should not be reached, since Chalk doesn't represent
344 // function pointers with TypeName
345 unreachable!()
346 }
347 }
348 }
349
350 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor {
351 match type_name {
352 TypeName::Adt(struct_id) => TypeCtor::Adt(struct_id.0),
353 TypeName::AssociatedType(type_id) => {
354 TypeCtor::AssociatedType(from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0)
355 }
356 TypeName::OpaqueType(opaque_type_id) => {
357 TypeCtor::OpaqueType(from_chalk(db, opaque_type_id))
358 }
359
360 TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool,
361 TypeName::Scalar(Scalar::Char) => TypeCtor::Char,
362 TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(IntTy {
363 signedness: Signedness::Signed,
364 bitness: bitness_from_chalk_int(int_ty),
365 }),
366 TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(IntTy {
367 signedness: Signedness::Unsigned,
368 bitness: bitness_from_chalk_uint(uint_ty),
369 }),
370 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => {
371 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })
372 }
373 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => {
374 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })
375 }
376 TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 },
377 TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)),
378 TypeName::Slice => TypeCtor::Slice,
379 TypeName::Ref(mutability) => TypeCtor::Ref(from_chalk(db, mutability)),
380 TypeName::Str => TypeCtor::Str,
381 TypeName::Never => TypeCtor::Never,
382
383 TypeName::FnDef(fn_def_id) => {
384 let callable_def = from_chalk(db, fn_def_id);
385 TypeCtor::FnDef(callable_def)
386 }
387 TypeName::Array => TypeCtor::Array,
388
389 TypeName::Closure(id) => {
390 let id: crate::db::ClosureId = id.into();
391 let (def, expr) = db.lookup_intern_closure(id);
392 TypeCtor::Closure { def, expr }
393 }
394
395 TypeName::Foreign(foreign_def_id) => {
396 TypeCtor::ForeignType(from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0)
397 }
398
399 TypeName::Error => {
400 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
401 unreachable!()
402 }
403 TypeName::Generator(_) => unimplemented!(), // FIXME
404 TypeName::GeneratorWitness(_) => unimplemented!(), // FIXME
405 }
406 }
407}
408
409fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness { 366fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness {
410 use chalk_ir::UintTy; 367 use chalk_ir::UintTy;
411 368
@@ -507,7 +464,7 @@ impl ToChalk for CallableDefId {
507 } 464 }
508} 465}
509 466
510pub struct TypeAliasAsAssocType(pub TypeAliasId); 467pub(crate) struct TypeAliasAsAssocType(pub(crate) TypeAliasId);
511 468
512impl ToChalk for TypeAliasAsAssocType { 469impl ToChalk for TypeAliasAsAssocType {
513 type Chalk = AssocTypeId; 470 type Chalk = AssocTypeId;
@@ -521,7 +478,7 @@ impl ToChalk for TypeAliasAsAssocType {
521 } 478 }
522} 479}
523 480
524pub struct TypeAliasAsForeignType(pub TypeAliasId); 481pub(crate) struct TypeAliasAsForeignType(pub(crate) TypeAliasId);
525 482
526impl ToChalk for TypeAliasAsForeignType { 483impl ToChalk for TypeAliasAsForeignType {
527 type Chalk = ForeignDefId; 484 type Chalk = ForeignDefId;
@@ -535,7 +492,7 @@ impl ToChalk for TypeAliasAsForeignType {
535 } 492 }
536} 493}
537 494
538pub struct TypeAliasAsValue(pub TypeAliasId); 495pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId);
539 496
540impl ToChalk for TypeAliasAsValue { 497impl ToChalk for TypeAliasAsValue {
541 type Chalk = AssociatedTyValueId; 498 type Chalk = AssociatedTyValueId;
@@ -677,9 +634,9 @@ where
677 .kinds 634 .kinds
678 .iter() 635 .iter()
679 .map(|k| match k { 636 .map(|k| match k {
680 TyKind::General => chalk_ir::TyKind::General, 637 TyKind::General => chalk_ir::TyVariableKind::General,
681 TyKind::Integer => chalk_ir::TyKind::Integer, 638 TyKind::Integer => chalk_ir::TyVariableKind::Integer,
682 TyKind::Float => chalk_ir::TyKind::Float, 639 TyKind::Float => chalk_ir::TyVariableKind::Float,
683 }) 640 })
684 .map(|tk| { 641 .map(|tk| {
685 chalk_ir::CanonicalVarKind::new( 642 chalk_ir::CanonicalVarKind::new(
@@ -700,9 +657,9 @@ where
700 .iter(&Interner) 657 .iter(&Interner)
701 .map(|k| match k.kind { 658 .map(|k| match k.kind {
702 chalk_ir::VariableKind::Ty(tk) => match tk { 659 chalk_ir::VariableKind::Ty(tk) => match tk {
703 chalk_ir::TyKind::General => TyKind::General, 660 chalk_ir::TyVariableKind::General => TyKind::General,
704 chalk_ir::TyKind::Integer => TyKind::Integer, 661 chalk_ir::TyVariableKind::Integer => TyKind::Integer,
705 chalk_ir::TyKind::Float => TyKind::Float, 662 chalk_ir::TyVariableKind::Float => TyKind::Float,
706 }, 663 },
707 chalk_ir::VariableKind::Lifetime => panic!("unexpected lifetime from Chalk"), 664 chalk_ir::VariableKind::Lifetime => panic!("unexpected lifetime from Chalk"),
708 chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"), 665 chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"),
@@ -768,7 +725,8 @@ where
768 chalk_ir::Binders::new( 725 chalk_ir::Binders::new(
769 chalk_ir::VariableKinds::from_iter( 726 chalk_ir::VariableKinds::from_iter(
770 &Interner, 727 &Interner,
771 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars), 728 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
729 .take(num_vars),
772 ), 730 ),
773 value, 731 value,
774 ) 732 )
diff --git a/crates/hir_ty/src/traits/chalk/tls.rs b/crates/hir_ty/src/traits/chalk/tls.rs
index b4568cff6..75b16172e 100644
--- a/crates/hir_ty/src/traits/chalk/tls.rs
+++ b/crates/hir_ty/src/traits/chalk/tls.rs
@@ -1,114 +1,32 @@
1//! Implementation of Chalk debug helper functions using TLS. 1//! Implementation of Chalk debug helper functions using TLS.
2use std::fmt; 2use std::fmt;
3 3
4use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication, TypeName}; 4use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication};
5use itertools::Itertools; 5use itertools::Itertools;
6 6
7use super::{from_chalk, Interner, TypeAliasAsAssocType}; 7use super::{from_chalk, Interner, TypeAliasAsAssocType};
8use crate::{db::HirDatabase, CallableDefId, TypeCtor}; 8use crate::{db::HirDatabase, CallableDefId};
9use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId}; 9use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId};
10 10
11pub use unsafe_tls::{set_current_program, with_current_program}; 11pub(crate) use unsafe_tls::{set_current_program, with_current_program};
12 12
13pub struct DebugContext<'a>(&'a dyn HirDatabase); 13pub(crate) struct DebugContext<'a>(&'a dyn HirDatabase);
14 14
15impl DebugContext<'_> { 15impl DebugContext<'_> {
16 pub fn debug_struct_id( 16 pub(crate) fn debug_struct_id(
17 &self, 17 &self,
18 id: super::AdtId, 18 id: super::AdtId,
19 f: &mut fmt::Formatter<'_>, 19 f: &mut fmt::Formatter<'_>,
20 ) -> Result<(), fmt::Error> { 20 ) -> Result<(), fmt::Error> {
21 let type_ctor: TypeCtor = from_chalk(self.0, TypeName::Adt(id)); 21 let name = match id.0 {
22 match type_ctor { 22 AdtId::StructId(it) => self.0.struct_data(it).name.clone(),
23 TypeCtor::Bool => write!(f, "bool")?, 23 AdtId::UnionId(it) => self.0.union_data(it).name.clone(),
24 TypeCtor::Char => write!(f, "char")?, 24 AdtId::EnumId(it) => self.0.enum_data(it).name.clone(),
25 TypeCtor::Int(t) => write!(f, "{}", t)?, 25 };
26 TypeCtor::Float(t) => write!(f, "{}", t)?, 26 write!(f, "{}", name)
27 TypeCtor::Str => write!(f, "str")?,
28 TypeCtor::Slice => write!(f, "slice")?,
29 TypeCtor::Array => write!(f, "array")?,
30 TypeCtor::RawPtr(m) => write!(f, "*{}", m.as_keyword_for_ptr())?,
31 TypeCtor::Ref(m) => write!(f, "&{}", m.as_keyword_for_ref())?,
32 TypeCtor::Never => write!(f, "!")?,
33 TypeCtor::Tuple { .. } => {
34 write!(f, "()")?;
35 }
36 TypeCtor::FnPtr { .. } => {
37 write!(f, "fn")?;
38 }
39 TypeCtor::FnDef(def) => {
40 let name = match def {
41 CallableDefId::FunctionId(ff) => self.0.function_data(ff).name.clone(),
42 CallableDefId::StructId(s) => self.0.struct_data(s).name.clone(),
43 CallableDefId::EnumVariantId(e) => {
44 let enum_data = self.0.enum_data(e.parent);
45 enum_data.variants[e.local_id].name.clone()
46 }
47 };
48 match def {
49 CallableDefId::FunctionId(_) => write!(f, "{{fn {}}}", name)?,
50 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {
51 write!(f, "{{ctor {}}}", name)?
52 }
53 }
54 }
55 TypeCtor::Adt(def_id) => {
56 let name = match def_id {
57 AdtId::StructId(it) => self.0.struct_data(it).name.clone(),
58 AdtId::UnionId(it) => self.0.union_data(it).name.clone(),
59 AdtId::EnumId(it) => self.0.enum_data(it).name.clone(),
60 };
61 write!(f, "{}", name)?;
62 }
63 TypeCtor::AssociatedType(type_alias) => {
64 let trait_ = match type_alias.lookup(self.0.upcast()).container {
65 AssocContainerId::TraitId(it) => it,
66 _ => panic!("not an associated type"),
67 };
68 let trait_name = self.0.trait_data(trait_).name.clone();
69 let name = self.0.type_alias_data(type_alias).name.clone();
70 write!(f, "{}::{}", trait_name, name)?;
71 }
72 TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id {
73 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
74 write!(f, "{{impl trait {} of {:?}}}", idx, func)?;
75 }
76 crate::OpaqueTyId::AsyncBlockTypeImplTrait(def, idx) => {
77 write!(f, "{{impl trait of async block {} of {:?}}}", idx.into_raw(), def)?;
78 }
79 },
80 TypeCtor::ForeignType(type_alias) => {
81 let name = self.0.type_alias_data(type_alias).name.clone();
82 write!(f, "{}", name)?;
83 }
84 TypeCtor::Closure { def, expr } => {
85 write!(f, "{{closure {:?} in ", expr.into_raw())?;
86 match def {
87 DefWithBodyId::FunctionId(func) => {
88 write!(f, "fn {}", self.0.function_data(func).name)?
89 }
90 DefWithBodyId::StaticId(s) => {
91 if let Some(name) = self.0.static_data(s).name.as_ref() {
92 write!(f, "body of static {}", name)?;
93 } else {
94 write!(f, "body of unnamed static {:?}", s)?;
95 }
96 }
97 DefWithBodyId::ConstId(c) => {
98 if let Some(name) = self.0.const_data(c).name.as_ref() {
99 write!(f, "body of const {}", name)?;
100 } else {
101 write!(f, "body of unnamed const {:?}", c)?;
102 }
103 }
104 };
105 write!(f, "}}")?;
106 }
107 }
108 Ok(())
109 } 27 }
110 28
111 pub fn debug_trait_id( 29 pub(crate) fn debug_trait_id(
112 &self, 30 &self,
113 id: super::TraitId, 31 id: super::TraitId,
114 fmt: &mut fmt::Formatter<'_>, 32 fmt: &mut fmt::Formatter<'_>,
@@ -118,7 +36,7 @@ impl DebugContext<'_> {
118 write!(fmt, "{}", trait_data.name) 36 write!(fmt, "{}", trait_data.name)
119 } 37 }
120 38
121 pub fn debug_assoc_type_id( 39 pub(crate) fn debug_assoc_type_id(
122 &self, 40 &self,
123 id: super::AssocTypeId, 41 id: super::AssocTypeId,
124 fmt: &mut fmt::Formatter<'_>, 42 fmt: &mut fmt::Formatter<'_>,
@@ -133,7 +51,7 @@ impl DebugContext<'_> {
133 write!(fmt, "{}::{}", trait_data.name, type_alias_data.name) 51 write!(fmt, "{}::{}", trait_data.name, type_alias_data.name)
134 } 52 }
135 53
136 pub fn debug_opaque_ty_id( 54 pub(crate) fn debug_opaque_ty_id(
137 &self, 55 &self,
138 opaque_ty_id: chalk_ir::OpaqueTyId<Interner>, 56 opaque_ty_id: chalk_ir::OpaqueTyId<Interner>,
139 fmt: &mut fmt::Formatter<'_>, 57 fmt: &mut fmt::Formatter<'_>,
@@ -141,7 +59,7 @@ impl DebugContext<'_> {
141 fmt.debug_struct("OpaqueTyId").field("index", &opaque_ty_id.0).finish() 59 fmt.debug_struct("OpaqueTyId").field("index", &opaque_ty_id.0).finish()
142 } 60 }
143 61
144 pub fn debug_alias( 62 pub(crate) fn debug_alias(
145 &self, 63 &self,
146 alias_ty: &AliasTy<Interner>, 64 alias_ty: &AliasTy<Interner>,
147 fmt: &mut fmt::Formatter<'_>, 65 fmt: &mut fmt::Formatter<'_>,
@@ -152,7 +70,7 @@ impl DebugContext<'_> {
152 } 70 }
153 } 71 }
154 72
155 pub fn debug_projection_ty( 73 pub(crate) fn debug_projection_ty(
156 &self, 74 &self,
157 projection_ty: &chalk_ir::ProjectionTy<Interner>, 75 projection_ty: &chalk_ir::ProjectionTy<Interner>,
158 fmt: &mut fmt::Formatter<'_>, 76 fmt: &mut fmt::Formatter<'_>,
@@ -177,7 +95,7 @@ impl DebugContext<'_> {
177 write!(fmt, ">::{}", type_alias_data.name) 95 write!(fmt, ">::{}", type_alias_data.name)
178 } 96 }
179 97
180 pub fn debug_opaque_ty( 98 pub(crate) fn debug_opaque_ty(
181 &self, 99 &self,
182 opaque_ty: &chalk_ir::OpaqueTy<Interner>, 100 opaque_ty: &chalk_ir::OpaqueTy<Interner>,
183 fmt: &mut fmt::Formatter<'_>, 101 fmt: &mut fmt::Formatter<'_>,
@@ -185,7 +103,7 @@ impl DebugContext<'_> {
185 write!(fmt, "{:?}", opaque_ty.opaque_ty_id) 103 write!(fmt, "{:?}", opaque_ty.opaque_ty_id)
186 } 104 }
187 105
188 pub fn debug_ty( 106 pub(crate) fn debug_ty(
189 &self, 107 &self,
190 ty: &chalk_ir::Ty<Interner>, 108 ty: &chalk_ir::Ty<Interner>,
191 fmt: &mut fmt::Formatter<'_>, 109 fmt: &mut fmt::Formatter<'_>,
@@ -193,7 +111,7 @@ impl DebugContext<'_> {
193 write!(fmt, "{:?}", ty.data(&Interner)) 111 write!(fmt, "{:?}", ty.data(&Interner))
194 } 112 }
195 113
196 pub fn debug_lifetime( 114 pub(crate) fn debug_lifetime(
197 &self, 115 &self,
198 lifetime: &Lifetime<Interner>, 116 lifetime: &Lifetime<Interner>,
199 fmt: &mut fmt::Formatter<'_>, 117 fmt: &mut fmt::Formatter<'_>,
@@ -201,7 +119,7 @@ impl DebugContext<'_> {
201 write!(fmt, "{:?}", lifetime.data(&Interner)) 119 write!(fmt, "{:?}", lifetime.data(&Interner))
202 } 120 }
203 121
204 pub fn debug_generic_arg( 122 pub(crate) fn debug_generic_arg(
205 &self, 123 &self,
206 parameter: &GenericArg<Interner>, 124 parameter: &GenericArg<Interner>,
207 fmt: &mut fmt::Formatter<'_>, 125 fmt: &mut fmt::Formatter<'_>,
@@ -209,7 +127,7 @@ impl DebugContext<'_> {
209 write!(fmt, "{:?}", parameter.data(&Interner).inner_debug()) 127 write!(fmt, "{:?}", parameter.data(&Interner).inner_debug())
210 } 128 }
211 129
212 pub fn debug_goal( 130 pub(crate) fn debug_goal(
213 &self, 131 &self,
214 goal: &Goal<Interner>, 132 goal: &Goal<Interner>,
215 fmt: &mut fmt::Formatter<'_>, 133 fmt: &mut fmt::Formatter<'_>,
@@ -218,7 +136,7 @@ impl DebugContext<'_> {
218 write!(fmt, "{:?}", goal_data) 136 write!(fmt, "{:?}", goal_data)
219 } 137 }
220 138
221 pub fn debug_goals( 139 pub(crate) fn debug_goals(
222 &self, 140 &self,
223 goals: &Goals<Interner>, 141 goals: &Goals<Interner>,
224 fmt: &mut fmt::Formatter<'_>, 142 fmt: &mut fmt::Formatter<'_>,
@@ -226,7 +144,7 @@ impl DebugContext<'_> {
226 write!(fmt, "{:?}", goals.debug(&Interner)) 144 write!(fmt, "{:?}", goals.debug(&Interner))
227 } 145 }
228 146
229 pub fn debug_program_clause_implication( 147 pub(crate) fn debug_program_clause_implication(
230 &self, 148 &self,
231 pci: &ProgramClauseImplication<Interner>, 149 pci: &ProgramClauseImplication<Interner>,
232 fmt: &mut fmt::Formatter<'_>, 150 fmt: &mut fmt::Formatter<'_>,
@@ -234,15 +152,7 @@ impl DebugContext<'_> {
234 write!(fmt, "{:?}", pci.debug(&Interner)) 152 write!(fmt, "{:?}", pci.debug(&Interner))
235 } 153 }
236 154
237 pub fn debug_application_ty( 155 pub(crate) fn debug_substitution(
238 &self,
239 application_ty: &chalk_ir::ApplicationTy<Interner>,
240 fmt: &mut fmt::Formatter<'_>,
241 ) -> Result<(), fmt::Error> {
242 write!(fmt, "{:?}", application_ty.debug(&Interner))
243 }
244
245 pub fn debug_substitution(
246 &self, 156 &self,
247 substitution: &chalk_ir::Substitution<Interner>, 157 substitution: &chalk_ir::Substitution<Interner>,
248 fmt: &mut fmt::Formatter<'_>, 158 fmt: &mut fmt::Formatter<'_>,
@@ -250,7 +160,7 @@ impl DebugContext<'_> {
250 write!(fmt, "{:?}", substitution.debug(&Interner)) 160 write!(fmt, "{:?}", substitution.debug(&Interner))
251 } 161 }
252 162
253 pub fn debug_separator_trait_ref( 163 pub(crate) fn debug_separator_trait_ref(
254 &self, 164 &self,
255 separator_trait_ref: &chalk_ir::SeparatorTraitRef<Interner>, 165 separator_trait_ref: &chalk_ir::SeparatorTraitRef<Interner>,
256 fmt: &mut fmt::Formatter<'_>, 166 fmt: &mut fmt::Formatter<'_>,
@@ -258,7 +168,7 @@ impl DebugContext<'_> {
258 write!(fmt, "{:?}", separator_trait_ref.debug(&Interner)) 168 write!(fmt, "{:?}", separator_trait_ref.debug(&Interner))
259 } 169 }
260 170
261 pub fn debug_fn_def_id( 171 pub(crate) fn debug_fn_def_id(
262 &self, 172 &self,
263 fn_def_id: chalk_ir::FnDefId<Interner>, 173 fn_def_id: chalk_ir::FnDefId<Interner>,
264 fmt: &mut fmt::Formatter<'_>, 174 fmt: &mut fmt::Formatter<'_>,
@@ -280,7 +190,7 @@ impl DebugContext<'_> {
280 } 190 }
281 } 191 }
282 192
283 pub fn debug_const( 193 pub(crate) fn debug_const(
284 &self, 194 &self,
285 _constant: &chalk_ir::Const<Interner>, 195 _constant: &chalk_ir::Const<Interner>,
286 fmt: &mut fmt::Formatter<'_>, 196 fmt: &mut fmt::Formatter<'_>,
@@ -288,42 +198,42 @@ impl DebugContext<'_> {
288 write!(fmt, "const") 198 write!(fmt, "const")
289 } 199 }
290 200
291 pub fn debug_variable_kinds( 201 pub(crate) fn debug_variable_kinds(
292 &self, 202 &self,
293 variable_kinds: &chalk_ir::VariableKinds<Interner>, 203 variable_kinds: &chalk_ir::VariableKinds<Interner>,
294 fmt: &mut fmt::Formatter<'_>, 204 fmt: &mut fmt::Formatter<'_>,
295 ) -> fmt::Result { 205 ) -> fmt::Result {
296 write!(fmt, "{:?}", variable_kinds.as_slice(&Interner)) 206 write!(fmt, "{:?}", variable_kinds.as_slice(&Interner))
297 } 207 }
298 pub fn debug_variable_kinds_with_angles( 208 pub(crate) fn debug_variable_kinds_with_angles(
299 &self, 209 &self,
300 variable_kinds: &chalk_ir::VariableKinds<Interner>, 210 variable_kinds: &chalk_ir::VariableKinds<Interner>,
301 fmt: &mut fmt::Formatter<'_>, 211 fmt: &mut fmt::Formatter<'_>,
302 ) -> fmt::Result { 212 ) -> fmt::Result {
303 write!(fmt, "{:?}", variable_kinds.inner_debug(&Interner)) 213 write!(fmt, "{:?}", variable_kinds.inner_debug(&Interner))
304 } 214 }
305 pub fn debug_canonical_var_kinds( 215 pub(crate) fn debug_canonical_var_kinds(
306 &self, 216 &self,
307 canonical_var_kinds: &chalk_ir::CanonicalVarKinds<Interner>, 217 canonical_var_kinds: &chalk_ir::CanonicalVarKinds<Interner>,
308 fmt: &mut fmt::Formatter<'_>, 218 fmt: &mut fmt::Formatter<'_>,
309 ) -> fmt::Result { 219 ) -> fmt::Result {
310 write!(fmt, "{:?}", canonical_var_kinds.as_slice(&Interner)) 220 write!(fmt, "{:?}", canonical_var_kinds.as_slice(&Interner))
311 } 221 }
312 pub fn debug_program_clause( 222 pub(crate) fn debug_program_clause(
313 &self, 223 &self,
314 clause: &chalk_ir::ProgramClause<Interner>, 224 clause: &chalk_ir::ProgramClause<Interner>,
315 fmt: &mut fmt::Formatter<'_>, 225 fmt: &mut fmt::Formatter<'_>,
316 ) -> fmt::Result { 226 ) -> fmt::Result {
317 write!(fmt, "{:?}", clause.data(&Interner)) 227 write!(fmt, "{:?}", clause.data(&Interner))
318 } 228 }
319 pub fn debug_program_clauses( 229 pub(crate) fn debug_program_clauses(
320 &self, 230 &self,
321 clauses: &chalk_ir::ProgramClauses<Interner>, 231 clauses: &chalk_ir::ProgramClauses<Interner>,
322 fmt: &mut fmt::Formatter<'_>, 232 fmt: &mut fmt::Formatter<'_>,
323 ) -> fmt::Result { 233 ) -> fmt::Result {
324 write!(fmt, "{:?}", clauses.as_slice(&Interner)) 234 write!(fmt, "{:?}", clauses.as_slice(&Interner))
325 } 235 }
326 pub fn debug_quantified_where_clauses( 236 pub(crate) fn debug_quantified_where_clauses(
327 &self, 237 &self,
328 clauses: &chalk_ir::QuantifiedWhereClauses<Interner>, 238 clauses: &chalk_ir::QuantifiedWhereClauses<Interner>,
329 fmt: &mut fmt::Formatter<'_>, 239 fmt: &mut fmt::Formatter<'_>,
@@ -339,7 +249,7 @@ mod unsafe_tls {
339 249
340 scoped_thread_local!(static PROGRAM: DebugContext); 250 scoped_thread_local!(static PROGRAM: DebugContext);
341 251
342 pub fn with_current_program<R>( 252 pub(crate) fn with_current_program<R>(
343 op: impl for<'a> FnOnce(Option<&'a DebugContext<'a>>) -> R, 253 op: impl for<'a> FnOnce(Option<&'a DebugContext<'a>>) -> R,
344 ) -> R { 254 ) -> R {
345 if PROGRAM.is_set() { 255 if PROGRAM.is_set() {
@@ -349,7 +259,7 @@ mod unsafe_tls {
349 } 259 }
350 } 260 }
351 261
352 pub fn set_current_program<OP, R>(p: &dyn HirDatabase, op: OP) -> R 262 pub(crate) fn set_current_program<OP, R>(p: &dyn HirDatabase, op: OP) -> R
353 where 263 where
354 OP: FnOnce() -> R, 264 OP: FnOnce() -> R,
355 { 265 {