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/display.rs37
-rw-r--r--crates/hir_ty/src/infer/expr.rs11
-rw-r--r--crates/hir_ty/src/infer/pat.rs14
-rw-r--r--crates/hir_ty/src/lib.rs45
-rw-r--r--crates/hir_ty/src/lower.rs10
-rw-r--r--crates/hir_ty/src/method_resolution.rs8
-rw-r--r--crates/hir_ty/src/tests/method_resolution.rs36
-rw-r--r--crates/hir_ty/src/tests/patterns.rs25
-rw-r--r--crates/hir_ty/src/tests/simple.rs45
-rw-r--r--crates/hir_ty/src/tests/traits.rs40
-rw-r--r--crates/hir_ty/src/traits/chalk.rs127
-rw-r--r--crates/hir_ty/src/traits/chalk/interner.rs1
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs69
-rw-r--r--crates/hir_ty/src/traits/chalk/tls.rs14
15 files changed, 401 insertions, 87 deletions
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index 7d02aaf95..bc86df2b1 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.25.0" } 20chalk-solve = { version = "0.27.0" }
21chalk-ir = { version = "0.25.0" } 21chalk-ir = { version = "0.27.0" }
22chalk-recursive = { version = "0.25.0" } 22chalk-recursive = { version = "0.27.0" }
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/display.rs b/crates/hir_ty/src/display.rs
index 64b68014d..f389c5a4b 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -380,20 +380,34 @@ impl HirDisplay for ApplicationTy {
380 write!(f, ">")?; 380 write!(f, ">")?;
381 } 381 }
382 } 382 }
383 TypeCtor::ForeignType(type_alias) => {
384 let type_alias = f.db.type_alias_data(type_alias);
385 write!(f, "{}", type_alias.name)?;
386 if self.parameters.len() > 0 {
387 write!(f, "<")?;
388 f.write_joined(&*self.parameters.0, ", ")?;
389 write!(f, ">")?;
390 }
391 }
383 TypeCtor::OpaqueType(opaque_ty_id) => { 392 TypeCtor::OpaqueType(opaque_ty_id) => {
384 let bounds = match opaque_ty_id { 393 match opaque_ty_id {
385 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 394 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
386 let datas = 395 let datas =
387 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 396 f.db.return_type_impl_traits(func).expect("impl trait id without data");
388 let data = (*datas) 397 let data = (*datas)
389 .as_ref() 398 .as_ref()
390 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 399 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
391 data.subst(&self.parameters) 400 let bounds = data.subst(&self.parameters);
401 write!(f, "impl ")?;
402 write_bounds_like_dyn_trait(&bounds.value, f)?;
403 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
392 } 404 }
393 }; 405 OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
394 write!(f, "impl ")?; 406 write!(f, "impl Future<Output = ")?;
395 write_bounds_like_dyn_trait(&bounds.value, f)?; 407 self.parameters[0].hir_fmt(f)?;
396 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution 408 write!(f, ">")?;
409 }
410 }
397 } 411 }
398 TypeCtor::Closure { .. } => { 412 TypeCtor::Closure { .. } => {
399 let sig = self.parameters[0].callable_sig(f.db); 413 let sig = self.parameters[0].callable_sig(f.db);
@@ -474,18 +488,21 @@ impl HirDisplay for Ty {
474 write_bounds_like_dyn_trait(predicates, f)?; 488 write_bounds_like_dyn_trait(predicates, f)?;
475 } 489 }
476 Ty::Opaque(opaque_ty) => { 490 Ty::Opaque(opaque_ty) => {
477 let bounds = match opaque_ty.opaque_ty_id { 491 match opaque_ty.opaque_ty_id {
478 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 492 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
479 let datas = 493 let datas =
480 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 494 f.db.return_type_impl_traits(func).expect("impl trait id without data");
481 let data = (*datas) 495 let data = (*datas)
482 .as_ref() 496 .as_ref()
483 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 497 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
484 data.subst(&opaque_ty.parameters) 498 let bounds = data.subst(&opaque_ty.parameters);
499 write!(f, "impl ")?;
500 write_bounds_like_dyn_trait(&bounds.value, f)?;
501 }
502 OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
503 write!(f, "{{async block}}")?;
485 } 504 }
486 }; 505 };
487 write!(f, "impl ")?;
488 write_bounds_like_dyn_trait(&bounds.value, f)?;
489 } 506 }
490 Ty::Unknown => write!(f, "{{unknown}}")?, 507 Ty::Unknown => write!(f, "{{unknown}}")?,
491 Ty::Infer(..) => write!(f, "_")?, 508 Ty::Infer(..) => write!(f, "_")?,
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index a2f849d02..0a141b9cb 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -17,8 +17,8 @@ use crate::{
17 autoderef, method_resolution, op, 17 autoderef, method_resolution, op,
18 traits::{FnTrait, InEnvironment}, 18 traits::{FnTrait, InEnvironment},
19 utils::{generics, variant_data, Generics}, 19 utils::{generics, variant_data, Generics},
20 ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, Rawness, Substs, 20 ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, OpaqueTyId,
21 TraitRef, Ty, TypeCtor, 21 Rawness, Substs, TraitRef, Ty, TypeCtor,
22}; 22};
23 23
24use super::{ 24use super::{
@@ -146,6 +146,13 @@ impl<'a> InferenceContext<'a> {
146 // FIXME should be std::result::Result<{inner}, _> 146 // FIXME should be std::result::Result<{inner}, _>
147 Ty::Unknown 147 Ty::Unknown
148 } 148 }
149 Expr::Async { body } => {
150 // Use the first type parameter as the output type of future.
151 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
152 let inner_ty = self.infer_expr(*body, &Expectation::none());
153 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body);
154 Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty)
155 }
149 Expr::Loop { body, label } => { 156 Expr::Loop { body, label } => {
150 self.breakables.push(BreakableContext { 157 self.breakables.push(BreakableContext {
151 may_break: false, 158 may_break: false,
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index dde38bc39..cde2ab82b 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -209,6 +209,18 @@ impl<'a> InferenceContext<'a> {
209 end_ty 209 end_ty
210 } 210 }
211 Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())), 211 Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())),
212 Pat::Box { inner } => match self.resolve_boxed_box() {
213 Some(box_adt) => {
214 let inner_expected = match expected.as_adt() {
215 Some((adt, substs)) if adt == box_adt => substs.as_single(),
216 _ => &Ty::Unknown,
217 };
218
219 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm);
220 Ty::apply_one(TypeCtor::Adt(box_adt), inner_ty)
221 }
222 None => Ty::Unknown,
223 },
212 Pat::Missing => Ty::Unknown, 224 Pat::Missing => Ty::Unknown,
213 }; 225 };
214 // use a new type variable if we got Ty::Unknown here 226 // use a new type variable if we got Ty::Unknown here
@@ -236,6 +248,6 @@ fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool {
236 Expr::Literal(Literal::String(..)) => false, 248 Expr::Literal(Literal::String(..)) => false,
237 _ => true, 249 _ => true,
238 }, 250 },
239 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false, 251 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Box { .. } | Pat::Missing => false,
240 } 252 }
241} 253}
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 1e748476a..768d95eff 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -129,10 +129,14 @@ pub enum TypeCtor {
129 129
130 /// This represents a placeholder for an opaque type in situations where we 130 /// This represents a placeholder for an opaque type in situations where we
131 /// don't know the hidden type (i.e. currently almost always). This is 131 /// don't know the hidden type (i.e. currently almost always). This is
132 /// analogous to the `AssociatedType` type constructor. As with that one, 132 /// analogous to the `AssociatedType` type constructor.
133 /// these are only produced by Chalk. 133 /// It is also used as the type of async block, with one type parameter
134 /// representing the Future::Output type.
134 OpaqueType(OpaqueTyId), 135 OpaqueType(OpaqueTyId),
135 136
137 /// Represents a foreign type declared in external blocks.
138 ForeignType(TypeAliasId),
139
136 /// The type of a specific closure. 140 /// The type of a specific closure.
137 /// 141 ///
138 /// The closure signature is stored in a `FnPtr` type in the first type 142 /// The closure signature is stored in a `FnPtr` type in the first type
@@ -167,12 +171,18 @@ impl TypeCtor {
167 let generic_params = generics(db.upcast(), type_alias.into()); 171 let generic_params = generics(db.upcast(), type_alias.into());
168 generic_params.len() 172 generic_params.len()
169 } 173 }
174 TypeCtor::ForeignType(type_alias) => {
175 let generic_params = generics(db.upcast(), type_alias.into());
176 generic_params.len()
177 }
170 TypeCtor::OpaqueType(opaque_ty_id) => { 178 TypeCtor::OpaqueType(opaque_ty_id) => {
171 match opaque_ty_id { 179 match opaque_ty_id {
172 OpaqueTyId::ReturnTypeImplTrait(func, _) => { 180 OpaqueTyId::ReturnTypeImplTrait(func, _) => {
173 let generic_params = generics(db.upcast(), func.into()); 181 let generic_params = generics(db.upcast(), func.into());
174 generic_params.len() 182 generic_params.len()
175 } 183 }
184 // 1 param representing Future::Output type.
185 OpaqueTyId::AsyncBlockTypeImplTrait(..) => 1,
176 } 186 }
177 } 187 }
178 TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1, 188 TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1,
@@ -201,10 +211,14 @@ impl TypeCtor {
201 TypeCtor::AssociatedType(type_alias) => { 211 TypeCtor::AssociatedType(type_alias) => {
202 Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate) 212 Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate)
203 } 213 }
214 TypeCtor::ForeignType(type_alias) => {
215 Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate)
216 }
204 TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id { 217 TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id {
205 OpaqueTyId::ReturnTypeImplTrait(func, _) => { 218 OpaqueTyId::ReturnTypeImplTrait(func, _) => {
206 Some(func.lookup(db.upcast()).module(db.upcast()).krate) 219 Some(func.lookup(db.upcast()).module(db.upcast()).krate)
207 } 220 }
221 OpaqueTyId::AsyncBlockTypeImplTrait(def, _) => Some(def.module(db.upcast()).krate),
208 }, 222 },
209 } 223 }
210 } 224 }
@@ -227,6 +241,7 @@ impl TypeCtor {
227 TypeCtor::Adt(adt) => Some(adt.into()), 241 TypeCtor::Adt(adt) => Some(adt.into()),
228 TypeCtor::FnDef(callable) => Some(callable.into()), 242 TypeCtor::FnDef(callable) => Some(callable.into()),
229 TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), 243 TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()),
244 TypeCtor::ForeignType(type_alias) => Some(type_alias.into()),
230 TypeCtor::OpaqueType(_impl_trait_id) => None, 245 TypeCtor::OpaqueType(_impl_trait_id) => None,
231 } 246 }
232 } 247 }
@@ -843,6 +858,29 @@ impl Ty {
843 858
844 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { 859 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
845 match self { 860 match self {
861 Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => {
862 match opaque_ty_id {
863 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
864 let krate = def.module(db.upcast()).krate;
865 if let Some(future_trait) = db
866 .lang_item(krate, "future_trait".into())
867 .and_then(|item| item.as_trait())
868 {
869 // This is only used by type walking.
870 // Parameters will be walked outside, and projection predicate is not used.
871 // So just provide the Future trait.
872 let impl_bound = GenericPredicate::Implemented(TraitRef {
873 trait_: future_trait,
874 substs: Substs::empty(),
875 });
876 Some(vec![impl_bound])
877 } else {
878 None
879 }
880 }
881 OpaqueTyId::ReturnTypeImplTrait(..) => None,
882 }
883 }
846 Ty::Opaque(opaque_ty) => { 884 Ty::Opaque(opaque_ty) => {
847 let predicates = match opaque_ty.opaque_ty_id { 885 let predicates = match opaque_ty.opaque_ty_id {
848 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 886 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
@@ -853,6 +891,8 @@ impl Ty {
853 data.subst(&opaque_ty.parameters) 891 data.subst(&opaque_ty.parameters)
854 }) 892 })
855 } 893 }
894 // It always has an parameter for Future::Output type.
895 OpaqueTyId::AsyncBlockTypeImplTrait(..) => unreachable!(),
856 }; 896 };
857 897
858 predicates.map(|it| it.value) 898 predicates.map(|it| it.value)
@@ -1065,6 +1105,7 @@ impl<T: TypeWalk> TypeWalk for Vec<T> {
1065#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] 1105#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
1066pub enum OpaqueTyId { 1106pub enum OpaqueTyId {
1067 ReturnTypeImplTrait(hir_def::FunctionId, u16), 1107 ReturnTypeImplTrait(hir_def::FunctionId, u16),
1108 AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId),
1068} 1109}
1069 1110
1070#[derive(Clone, PartialEq, Eq, Debug, Hash)] 1111#[derive(Clone, PartialEq, Eq, Debug, Hash)]
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index cd574e983..708e2af0f 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -1101,10 +1101,14 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1101 let resolver = t.resolver(db.upcast()); 1101 let resolver = t.resolver(db.upcast());
1102 let ctx = 1102 let ctx =
1103 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1103 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1104 let type_ref = &db.type_alias_data(t).type_ref;
1105 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1104 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1106 let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error)); 1105 if db.type_alias_data(t).is_extern {
1107 Binders::new(substs.len(), inner) 1106 Binders::new(substs.len(), Ty::apply(TypeCtor::ForeignType(t), substs))
1107 } else {
1108 let type_ref = &db.type_alias_data(t).type_ref;
1109 let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error));
1110 Binders::new(substs.len(), inner)
1111 }
1108} 1112}
1109 1113
1110#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 1114#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index ec59145c7..8961df404 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -250,6 +250,14 @@ impl Ty {
250 TypeCtor::Adt(def_id) => { 250 TypeCtor::Adt(def_id) => {
251 return Some(std::iter::once(def_id.module(db.upcast()).krate).collect()) 251 return Some(std::iter::once(def_id.module(db.upcast()).krate).collect())
252 } 252 }
253 TypeCtor::ForeignType(type_alias_id) => {
254 return Some(
255 std::iter::once(
256 type_alias_id.lookup(db.upcast()).module(db.upcast()).krate,
257 )
258 .collect(),
259 )
260 }
253 TypeCtor::Bool => lang_item_crate!("bool"), 261 TypeCtor::Bool => lang_item_crate!("bool"),
254 TypeCtor::Char => lang_item_crate!("char"), 262 TypeCtor::Char => lang_item_crate!("char"),
255 TypeCtor::Float(f) => match f.bitness { 263 TypeCtor::Float(f) => match f.bitness {
diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs
index 23b2601e6..0f17ff151 100644
--- a/crates/hir_ty/src/tests/method_resolution.rs
+++ b/crates/hir_ty/src/tests/method_resolution.rs
@@ -1051,3 +1051,39 @@ fn dyn_trait_super_trait_not_in_scope() {
1051 "#]], 1051 "#]],
1052 ); 1052 );
1053} 1053}
1054
1055#[test]
1056fn method_resolution_foreign_opaque_type() {
1057 check_infer(
1058 r#"
1059 extern "C" {
1060 type S;
1061 fn f() -> &'static S;
1062 }
1063
1064 impl S {
1065 fn foo(&self) -> bool {
1066 true
1067 }
1068 }
1069
1070 fn test() {
1071 let s = unsafe { f() };
1072 s.foo();
1073 }
1074 "#,
1075 expect![[r#"
1076 75..79 'self': &S
1077 89..109 '{ ... }': bool
1078 99..103 'true': bool
1079 123..167 '{ ...o(); }': ()
1080 133..134 's': &S
1081 137..151 'unsafe { f() }': &S
1082 144..151 '{ f() }': &S
1083 146..147 'f': fn f() -> &S
1084 146..149 'f()': &S
1085 157..158 's': &S
1086 157..164 's.foo()': bool
1087 "#]],
1088 );
1089}
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index aeb191c79..6a965ac4f 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -654,3 +654,28 @@ fn slice_tail_pattern() {
654 "#]], 654 "#]],
655 ); 655 );
656} 656}
657
658#[test]
659fn box_pattern() {
660 check_infer(
661 r#"
662 #[lang = "owned_box"]
663 pub struct Box<T>(T);
664
665 fn foo(params: Box<i32>) {
666 match params {
667 box integer => {}
668 }
669 }
670 "#,
671 expect![[r#"
672 52..58 'params': Box<i32>
673 70..124 '{ ... } }': ()
674 76..122 'match ... }': ()
675 82..88 'params': Box<i32>
676 99..110 'box integer': Box<i32>
677 103..110 'integer': i32
678 114..116 '{}': ()
679 "#]],
680 );
681}
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index 48db23a34..5b07948f3 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -1889,31 +1889,40 @@ fn fn_pointer_return() {
1889fn effects_smoke_test() { 1889fn effects_smoke_test() {
1890 check_infer( 1890 check_infer(
1891 r#" 1891 r#"
1892 fn main() { 1892 async fn main() {
1893 let x = unsafe { 92 }; 1893 let x = unsafe { 92 };
1894 let y = async { async { () }.await }; 1894 let y = async { async { () }.await };
1895 let z = try { () }; 1895 let z = try { () };
1896 let t = 'a: { 92 }; 1896 let t = 'a: { 92 };
1897 } 1897 }
1898
1899 #[prelude_import] use future::*;
1900
1901 mod future {
1902 #[lang = "future_trait"]
1903 pub trait Future { type Output; }
1904 }
1898 "#, 1905 "#,
1899 expect![[r#" 1906 expect![[r#"
1900 10..130 '{ ...2 }; }': () 1907 16..136 '{ ...2 }; }': ()
1901 20..21 'x': i32 1908 26..27 'x': i32
1902 24..37 'unsafe { 92 }': i32 1909 30..43 'unsafe { 92 }': i32
1903 31..37 '{ 92 }': i32 1910 37..43 '{ 92 }': i32
1904 33..35 '92': i32 1911 39..41 '92': i32
1905 47..48 'y': {unknown} 1912 53..54 'y': impl Future<Output = ()>
1906 57..79 '{ asyn...wait }': {unknown} 1913 57..85 'async ...wait }': impl Future<Output = ()>
1907 59..77 'async ....await': {unknown} 1914 63..85 '{ asyn...wait }': ()
1908 65..71 '{ () }': () 1915 65..77 'async { () }': impl Future<Output = ()>
1909 67..69 '()': () 1916 65..83 'async ....await': ()
1910 89..90 'z': {unknown} 1917 71..77 '{ () }': ()
1911 93..103 'try { () }': {unknown} 1918 73..75 '()': ()
1912 97..103 '{ () }': () 1919 95..96 'z': {unknown}
1913 99..101 '()': () 1920 99..109 'try { () }': {unknown}
1914 113..114 't': i32 1921 103..109 '{ () }': ()
1915 121..127 '{ 92 }': i32 1922 105..107 '()': ()
1916 123..125 '92': i32 1923 119..120 't': i32
1924 127..133 '{ 92 }': i32
1925 129..131 '92': i32
1917 "#]], 1926 "#]],
1918 ) 1927 )
1919} 1928}
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 1f1056962..41d097519 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -86,6 +86,46 @@ mod future {
86} 86}
87 87
88#[test] 88#[test]
89fn infer_async_block() {
90 check_types(
91 r#"
92//- /main.rs crate:main deps:core
93async fn test() {
94 let a = async { 42 };
95 a;
96// ^ impl Future<Output = i32>
97 let x = a.await;
98 x;
99// ^ i32
100 let b = async {}.await;
101 b;
102// ^ ()
103 let c = async {
104 let y = Option::None;
105 y
106 // ^ Option<u64>
107 };
108 let _: Option<u64> = c.await;
109 c;
110// ^ impl Future<Output = Option<u64>>
111}
112
113enum Option<T> { None, Some(T) }
114
115//- /core.rs crate:core
116#[prelude_import] use future::*;
117mod future {
118 #[lang = "future_trait"]
119 trait Future {
120 type Output;
121 }
122}
123
124"#,
125 );
126}
127
128#[test]
89fn infer_try() { 129fn infer_try() {
90 check_types( 130 check_types(
91 r#" 131 r#"
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 01b5717a3..27f0ed628 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -11,6 +11,7 @@ use hir_def::{
11 lang_item::{lang_attr, LangItemTarget}, 11 lang_item::{lang_attr, LangItemTarget},
12 AssocContainerId, AssocItemId, HasModule, Lookup, TypeAliasId, 12 AssocContainerId, AssocItemId, HasModule, Lookup, TypeAliasId,
13}; 13};
14use hir_expand::name::name;
14 15
15use super::ChalkContext; 16use super::ChalkContext;
16use crate::{ 17use crate::{
@@ -18,10 +19,12 @@ use crate::{
18 display::HirDisplay, 19 display::HirDisplay,
19 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, 20 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
20 utils::generics, 21 utils::generics,
21 CallableDefId, DebruijnIndex, FnSig, GenericPredicate, Substs, Ty, TypeCtor, 22 BoundVar, CallableDefId, DebruijnIndex, FnSig, GenericPredicate, ProjectionPredicate,
23 ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
22}; 24};
23use mapping::{ 25use mapping::{
24 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, 26 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsAssocType,
27 TypeAliasAsValue,
25}; 28};
26 29
27pub use self::interner::*; 30pub use self::interner::*;
@@ -166,27 +169,88 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
166 fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> { 169 fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> {
167 let interned_id = crate::db::InternedOpaqueTyId::from(id); 170 let interned_id = crate::db::InternedOpaqueTyId::from(id);
168 let full_id = self.db.lookup_intern_impl_trait_id(interned_id); 171 let full_id = self.db.lookup_intern_impl_trait_id(interned_id);
169 let (func, idx) = match full_id { 172 let bound = match full_id {
170 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => (func, idx), 173 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
171 }; 174 let datas = self
172 let datas = 175 .db
173 self.db.return_type_impl_traits(func).expect("impl trait id without impl traits"); 176 .return_type_impl_traits(func)
174 let data = &datas.value.impl_traits[idx as usize]; 177 .expect("impl trait id without impl traits");
175 let bound = OpaqueTyDatumBound { 178 let data = &datas.value.impl_traits[idx as usize];
176 bounds: make_binders( 179 let bound = OpaqueTyDatumBound {
177 data.bounds 180 bounds: make_binders(
178 .value 181 data.bounds
179 .iter() 182 .value
180 .cloned() 183 .iter()
181 .filter(|b| !b.is_error()) 184 .cloned()
182 .map(|b| b.to_chalk(self.db)) 185 .filter(|b| !b.is_error())
183 .collect(), 186 .map(|b| b.to_chalk(self.db))
184 1, 187 .collect(),
185 ), 188 1,
186 where_clauses: make_binders(vec![], 0), 189 ),
190 where_clauses: make_binders(vec![], 0),
191 };
192 let num_vars = datas.num_binders;
193 make_binders(bound, num_vars)
194 }
195 crate::OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
196 if let Some((future_trait, future_output)) = self
197 .db
198 .lang_item(self.krate, "future_trait".into())
199 .and_then(|item| item.as_trait())
200 .and_then(|trait_| {
201 let alias =
202 self.db.trait_data(trait_).associated_type_by_name(&name![Output])?;
203 Some((trait_, alias))
204 })
205 {
206 // Making up `AsyncBlock<T>: Future<Output = T>`
207 //
208 // |--------------------OpaqueTyDatum-------------------|
209 // |-------------OpaqueTyDatumBound--------------|
210 // for<T> <Self> [Future<Self>, Future::Output<Self> = T]
211 // ^1 ^0 ^0 ^0 ^1
212 let impl_bound = GenericPredicate::Implemented(TraitRef {
213 trait_: future_trait,
214 // Self type as the first parameter.
215 substs: Substs::single(Ty::Bound(BoundVar {
216 debruijn: DebruijnIndex::INNERMOST,
217 index: 0,
218 })),
219 });
220 let proj_bound = GenericPredicate::Projection(ProjectionPredicate {
221 // The parameter of the opaque type.
222 ty: Ty::Bound(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 }),
223 projection_ty: ProjectionTy {
224 associated_ty: future_output,
225 // Self type as the first parameter.
226 parameters: Substs::single(Ty::Bound(BoundVar::new(
227 DebruijnIndex::INNERMOST,
228 0,
229 ))),
230 },
231 });
232 let bound = OpaqueTyDatumBound {
233 bounds: make_binders(
234 vec![impl_bound.to_chalk(self.db), proj_bound.to_chalk(self.db)],
235 1,
236 ),
237 where_clauses: make_binders(vec![], 0),
238 };
239 // The opaque type has 1 parameter.
240 make_binders(bound, 1)
241 } else {
242 // If failed to find `Future::Output`, return empty bounds as fallback.
243 let bound = OpaqueTyDatumBound {
244 bounds: make_binders(vec![], 0),
245 where_clauses: make_binders(vec![], 0),
246 };
247 // The opaque type has 1 parameter.
248 make_binders(bound, 1)
249 }
250 }
187 }; 251 };
188 let num_vars = datas.num_binders; 252
189 Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound: make_binders(bound, num_vars) }) 253 Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound })
190 } 254 }
191 255
192 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> { 256 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> {
@@ -277,7 +341,7 @@ pub(crate) fn associated_ty_data_query(
277 id: AssocTypeId, 341 id: AssocTypeId,
278) -> Arc<AssociatedTyDatum> { 342) -> Arc<AssociatedTyDatum> {
279 debug!("associated_ty_data {:?}", id); 343 debug!("associated_ty_data {:?}", id);
280 let type_alias: TypeAliasId = from_chalk(db, id); 344 let type_alias: TypeAliasId = from_chalk::<TypeAliasAsAssocType, _>(db, id).0;
281 let trait_ = match type_alias.lookup(db.upcast()).container { 345 let trait_ = match type_alias.lookup(db.upcast()).container {
282 AssocContainerId::TraitId(t) => t, 346 AssocContainerId::TraitId(t) => t,
283 _ => panic!("associated type not in trait"), 347 _ => panic!("associated type not in trait"),
@@ -331,8 +395,10 @@ pub(crate) fn trait_datum_query(
331 fundamental: false, 395 fundamental: false,
332 }; 396 };
333 let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); 397 let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars);
334 let associated_ty_ids = 398 let associated_ty_ids = trait_data
335 trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect(); 399 .associated_types()
400 .map(|type_alias| TypeAliasAsAssocType(type_alias).to_chalk(db))
401 .collect();
336 let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses }; 402 let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses };
337 let well_known = 403 let well_known =
338 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name)); 404 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name));
@@ -370,6 +436,7 @@ fn lang_attr_from_well_known_trait(attr: WellKnownTrait) -> &'static str {
370 WellKnownTrait::FnMut => "fn_mut", 436 WellKnownTrait::FnMut => "fn_mut",
371 WellKnownTrait::Fn => "fn", 437 WellKnownTrait::Fn => "fn",
372 WellKnownTrait::Unsize => "unsize", 438 WellKnownTrait::Unsize => "unsize",
439 WellKnownTrait::Unpin => "unpin",
373 } 440 }
374} 441}
375 442
@@ -513,7 +580,7 @@ fn type_alias_associated_ty_value(
513 let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; 580 let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) };
514 let value = rust_ir::AssociatedTyValue { 581 let value = rust_ir::AssociatedTyValue {
515 impl_id: impl_id.to_chalk(db), 582 impl_id: impl_id.to_chalk(db),
516 associated_ty_id: assoc_ty.to_chalk(db), 583 associated_ty_id: TypeAliasAsAssocType(assoc_ty).to_chalk(db),
517 value: make_binders(value_bound, ty.num_binders), 584 value: make_binders(value_bound, ty.num_binders),
518 }; 585 };
519 Arc::new(value) 586 Arc::new(value)
@@ -548,9 +615,11 @@ pub(crate) fn fn_def_datum_query(
548 }; 615 };
549 let datum = FnDefDatum { 616 let datum = FnDefDatum {
550 id: fn_def_id, 617 id: fn_def_id,
551 abi: (), 618 sig: chalk_ir::FnSig {
552 safety: chalk_ir::Safety::Safe, 619 abi: (),
553 variadic: sig.value.is_varargs, 620 safety: chalk_ir::Safety::Safe,
621 variadic: sig.value.is_varargs,
622 },
554 binders: make_binders(bound, sig.num_binders), 623 binders: make_binders(bound, sig.num_binders),
555 }; 624 };
556 Arc::new(datum) 625 Arc::new(datum)
diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/traits/chalk/interner.rs
index eb35db3ff..f9304b7d0 100644
--- a/crates/hir_ty/src/traits/chalk/interner.rs
+++ b/crates/hir_ty/src/traits/chalk/interner.rs
@@ -12,6 +12,7 @@ pub struct Interner;
12 12
13pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>; 13pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
14pub type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; 14pub type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>;
15pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
15pub type TraitId = chalk_ir::TraitId<Interner>; 16pub type TraitId = chalk_ir::TraitId<Interner>;
16pub type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>; 17pub type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>;
17pub type AdtId = chalk_ir::AdtId<Interner>; 18pub type AdtId = chalk_ir::AdtId<Interner>;
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index d6bacba1d..d42f4bba9 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -34,9 +34,11 @@ impl ToChalk for Ty {
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::TyData::Function(chalk_ir::FnPointer {
36 num_binders: 0, 36 num_binders: 0,
37 abi: (), 37 sig: chalk_ir::FnSig {
38 safety: chalk_ir::Safety::Safe, 38 abi: (),
39 variadic: is_varargs, 39 safety: chalk_ir::Safety::Safe,
40 variadic: is_varargs,
41 },
40 substitution, 42 substitution,
41 }) 43 })
42 .intern(&Interner) 44 .intern(&Interner)
@@ -48,7 +50,7 @@ impl ToChalk for Ty {
48 } 50 }
49 }, 51 },
50 Ty::Projection(proj_ty) => { 52 Ty::Projection(proj_ty) => {
51 let associated_ty_id = proj_ty.associated_ty.to_chalk(db); 53 let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db);
52 let substitution = proj_ty.parameters.to_chalk(db); 54 let substitution = proj_ty.parameters.to_chalk(db);
53 chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { 55 chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
54 associated_ty_id, 56 associated_ty_id,
@@ -114,7 +116,8 @@ impl ToChalk for Ty {
114 Ty::Placeholder(db.lookup_intern_type_param_id(interned_id)) 116 Ty::Placeholder(db.lookup_intern_type_param_id(interned_id))
115 } 117 }
116 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Projection(proj)) => { 118 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Projection(proj)) => {
117 let associated_ty = from_chalk(db, proj.associated_ty_id); 119 let associated_ty =
120 from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0;
118 let parameters = from_chalk(db, proj.substitution); 121 let parameters = from_chalk(db, proj.substitution);
119 Ty::Projection(ProjectionTy { associated_ty, parameters }) 122 Ty::Projection(ProjectionTy { associated_ty, parameters })
120 } 123 }
@@ -125,7 +128,7 @@ impl ToChalk for Ty {
125 } 128 }
126 chalk_ir::TyData::Function(chalk_ir::FnPointer { 129 chalk_ir::TyData::Function(chalk_ir::FnPointer {
127 num_binders, 130 num_binders,
128 variadic, 131 sig: chalk_ir::FnSig { variadic, .. },
129 substitution, 132 substitution,
130 .. 133 ..
131 }) => { 134 }) => {
@@ -290,8 +293,9 @@ impl ToChalk for TypeCtor {
290 fn to_chalk(self, db: &dyn HirDatabase) -> TypeName<Interner> { 293 fn to_chalk(self, db: &dyn HirDatabase) -> TypeName<Interner> {
291 match self { 294 match self {
292 TypeCtor::AssociatedType(type_alias) => { 295 TypeCtor::AssociatedType(type_alias) => {
293 let type_id = type_alias.to_chalk(db); 296 let assoc_type = TypeAliasAsAssocType(type_alias);
294 TypeName::AssociatedType(type_id) 297 let assoc_type_id = assoc_type.to_chalk(db);
298 TypeName::AssociatedType(assoc_type_id)
295 } 299 }
296 300
297 TypeCtor::OpaqueType(impl_trait_id) => { 301 TypeCtor::OpaqueType(impl_trait_id) => {
@@ -299,6 +303,12 @@ impl ToChalk for TypeCtor {
299 TypeName::OpaqueType(id) 303 TypeName::OpaqueType(id)
300 } 304 }
301 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
302 TypeCtor::Bool => TypeName::Scalar(Scalar::Bool), 312 TypeCtor::Bool => TypeName::Scalar(Scalar::Bool),
303 TypeCtor::Char => TypeName::Scalar(Scalar::Char), 313 TypeCtor::Char => TypeName::Scalar(Scalar::Char),
304 TypeCtor::Int(int_ty) => TypeName::Scalar(int_ty_to_chalk(int_ty)), 314 TypeCtor::Int(int_ty) => TypeName::Scalar(int_ty_to_chalk(int_ty)),
@@ -339,7 +349,9 @@ impl ToChalk for TypeCtor {
339 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor { 349 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor {
340 match type_name { 350 match type_name {
341 TypeName::Adt(struct_id) => TypeCtor::Adt(struct_id.0), 351 TypeName::Adt(struct_id) => TypeCtor::Adt(struct_id.0),
342 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), 352 TypeName::AssociatedType(type_id) => {
353 TypeCtor::AssociatedType(from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0)
354 }
343 TypeName::OpaqueType(opaque_type_id) => { 355 TypeName::OpaqueType(opaque_type_id) => {
344 TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)) 356 TypeCtor::OpaqueType(from_chalk(db, opaque_type_id))
345 } 357 }
@@ -379,6 +391,10 @@ impl ToChalk for TypeCtor {
379 TypeCtor::Closure { def, expr } 391 TypeCtor::Closure { def, expr }
380 } 392 }
381 393
394 TypeName::Foreign(foreign_def_id) => {
395 TypeCtor::ForeignType(from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0)
396 }
397
382 TypeName::Error => { 398 TypeName::Error => {
383 // this should not be reached, since we don't represent TypeName::Error with TypeCtor 399 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
384 unreachable!() 400 unreachable!()
@@ -488,15 +504,31 @@ impl ToChalk for CallableDefId {
488 } 504 }
489} 505}
490 506
491impl ToChalk for TypeAliasId { 507pub struct TypeAliasAsAssocType(pub TypeAliasId);
508
509impl ToChalk for TypeAliasAsAssocType {
492 type Chalk = AssocTypeId; 510 type Chalk = AssocTypeId;
493 511
494 fn to_chalk(self, _db: &dyn HirDatabase) -> AssocTypeId { 512 fn to_chalk(self, _db: &dyn HirDatabase) -> AssocTypeId {
495 chalk_ir::AssocTypeId(self.as_intern_id()) 513 chalk_ir::AssocTypeId(self.0.as_intern_id())
514 }
515
516 fn from_chalk(_db: &dyn HirDatabase, assoc_type_id: AssocTypeId) -> TypeAliasAsAssocType {
517 TypeAliasAsAssocType(InternKey::from_intern_id(assoc_type_id.0))
518 }
519}
520
521pub struct TypeAliasAsForeignType(pub TypeAliasId);
522
523impl ToChalk for TypeAliasAsForeignType {
524 type Chalk = ForeignDefId;
525
526 fn to_chalk(self, _db: &dyn HirDatabase) -> ForeignDefId {
527 chalk_ir::ForeignDefId(self.0.as_intern_id())
496 } 528 }
497 529
498 fn from_chalk(_db: &dyn HirDatabase, type_alias_id: AssocTypeId) -> TypeAliasId { 530 fn from_chalk(_db: &dyn HirDatabase, foreign_def_id: ForeignDefId) -> TypeAliasAsForeignType {
499 InternKey::from_intern_id(type_alias_id.0) 531 TypeAliasAsForeignType(InternKey::from_intern_id(foreign_def_id.0))
500 } 532 }
501} 533}
502 534
@@ -580,7 +612,7 @@ impl ToChalk for ProjectionTy {
580 612
581 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> { 613 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> {
582 chalk_ir::ProjectionTy { 614 chalk_ir::ProjectionTy {
583 associated_ty_id: self.associated_ty.to_chalk(db), 615 associated_ty_id: TypeAliasAsAssocType(self.associated_ty).to_chalk(db),
584 substitution: self.parameters.to_chalk(db), 616 substitution: self.parameters.to_chalk(db),
585 } 617 }
586 } 618 }
@@ -590,7 +622,11 @@ impl ToChalk for ProjectionTy {
590 projection_ty: chalk_ir::ProjectionTy<Interner>, 622 projection_ty: chalk_ir::ProjectionTy<Interner>,
591 ) -> ProjectionTy { 623 ) -> ProjectionTy {
592 ProjectionTy { 624 ProjectionTy {
593 associated_ty: from_chalk(db, projection_ty.associated_ty_id), 625 associated_ty: from_chalk::<TypeAliasAsAssocType, _>(
626 db,
627 projection_ty.associated_ty_id,
628 )
629 .0,
594 parameters: from_chalk(db, projection_ty.substitution), 630 parameters: from_chalk(db, projection_ty.substitution),
595 } 631 }
596 } 632 }
@@ -789,7 +825,8 @@ pub(super) fn generic_predicate_to_inline_bound(
789 let alias_eq_bound = rust_ir::AliasEqBound { 825 let alias_eq_bound = rust_ir::AliasEqBound {
790 value: proj.ty.clone().to_chalk(db), 826 value: proj.ty.clone().to_chalk(db),
791 trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, 827 trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self },
792 associated_ty_id: proj.projection_ty.associated_ty.to_chalk(db), 828 associated_ty_id: TypeAliasAsAssocType(proj.projection_ty.associated_ty)
829 .to_chalk(db),
793 parameters: Vec::new(), // FIXME we don't support generic associated types yet 830 parameters: Vec::new(), // FIXME we don't support generic associated types yet
794 }; 831 };
795 Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) 832 Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound))
diff --git a/crates/hir_ty/src/traits/chalk/tls.rs b/crates/hir_ty/src/traits/chalk/tls.rs
index db915625c..b4568cff6 100644
--- a/crates/hir_ty/src/traits/chalk/tls.rs
+++ b/crates/hir_ty/src/traits/chalk/tls.rs
@@ -4,7 +4,7 @@ use std::fmt;
4use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication, TypeName}; 4use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication, TypeName};
5use itertools::Itertools; 5use itertools::Itertools;
6 6
7use super::{from_chalk, Interner}; 7use super::{from_chalk, Interner, TypeAliasAsAssocType};
8use crate::{db::HirDatabase, CallableDefId, TypeCtor}; 8use crate::{db::HirDatabase, CallableDefId, TypeCtor};
9use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId}; 9use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId};
10 10
@@ -73,7 +73,14 @@ impl DebugContext<'_> {
73 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 73 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
74 write!(f, "{{impl trait {} of {:?}}}", idx, func)?; 74 write!(f, "{{impl trait {} of {:?}}}", idx, func)?;
75 } 75 }
76 crate::OpaqueTyId::AsyncBlockTypeImplTrait(def, idx) => {
77 write!(f, "{{impl trait of async block {} of {:?}}}", idx.into_raw(), def)?;
78 }
76 }, 79 },
80 TypeCtor::ForeignType(type_alias) => {
81 let name = self.0.type_alias_data(type_alias).name.clone();
82 write!(f, "{}", name)?;
83 }
77 TypeCtor::Closure { def, expr } => { 84 TypeCtor::Closure { def, expr } => {
78 write!(f, "{{closure {:?} in ", expr.into_raw())?; 85 write!(f, "{{closure {:?} in ", expr.into_raw())?;
79 match def { 86 match def {
@@ -116,7 +123,7 @@ impl DebugContext<'_> {
116 id: super::AssocTypeId, 123 id: super::AssocTypeId,
117 fmt: &mut fmt::Formatter<'_>, 124 fmt: &mut fmt::Formatter<'_>,
118 ) -> Result<(), fmt::Error> { 125 ) -> Result<(), fmt::Error> {
119 let type_alias: TypeAliasId = from_chalk(self.0, id); 126 let type_alias: TypeAliasId = from_chalk::<TypeAliasAsAssocType, _>(self.0, id).0;
120 let type_alias_data = self.0.type_alias_data(type_alias); 127 let type_alias_data = self.0.type_alias_data(type_alias);
121 let trait_ = match type_alias.lookup(self.0.upcast()).container { 128 let trait_ = match type_alias.lookup(self.0.upcast()).container {
122 AssocContainerId::TraitId(t) => t, 129 AssocContainerId::TraitId(t) => t,
@@ -150,7 +157,8 @@ impl DebugContext<'_> {
150 projection_ty: &chalk_ir::ProjectionTy<Interner>, 157 projection_ty: &chalk_ir::ProjectionTy<Interner>,
151 fmt: &mut fmt::Formatter<'_>, 158 fmt: &mut fmt::Formatter<'_>,
152 ) -> Result<(), fmt::Error> { 159 ) -> Result<(), fmt::Error> {
153 let type_alias: TypeAliasId = from_chalk(self.0, projection_ty.associated_ty_id); 160 let type_alias: TypeAliasId =
161 from_chalk::<TypeAliasAsAssocType, _>(self.0, projection_ty.associated_ty_id).0;
154 let type_alias_data = self.0.type_alias_data(type_alias); 162 let type_alias_data = self.0.type_alias_data(type_alias);
155 let trait_ = match type_alias.lookup(self.0.upcast()).container { 163 let trait_ = match type_alias.lookup(self.0.upcast()).container {
156 AssocContainerId::TraitId(t) => t, 164 AssocContainerId::TraitId(t) => t,