aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-02-09 11:35:08 +0000
committerGitHub <[email protected]>2020-02-09 11:35:08 +0000
commit01836a0f35fa163025c64cabe1d0c34bb4f69c92 (patch)
treeaa1a3cf97173b2885f8b6d23002c73196f9a0b61 /crates
parent961a69b88f923d4477ca4f746a793217a0cc8576 (diff)
parenteefe02ce6e1750b771cf99125429358e87485745 (diff)
Merge #3050
3050: Refactor type parameters, implement argument position impl trait r=matklad a=flodiebold I wanted to implement APIT by lowering to type parameters because we need to do that anyway for correctness and don't need Chalk support for it; this grew into some more wide-ranging refactoring of how type parameters are handled :sweat_smile: - use Ty::Bound instead of Ty::Param to represent polymorphism, and explicitly count binders. This gets us closer to Chalk's way of doing things, and means that we now only use Param as a placeholder for an unknown type, e.g. within a generic function. I.e. we're never using Param in a situation where we want to substitute it, and the method to do that is gone; `subst` now always works on bound variables. (This changes how the types of generic functions print; previously, you'd get something like `fn identity<i32>(T) -> T`, but now we display the substituted signature `fn identity<i32>(i32) -> i32`, which I think makes more sense.) - once we do this, it's more natural to represent `Param` by a globally unique ID; the use of indices was mostly to make substituting easier. This also means we fix the bug where `Param` loses its name when going through Chalk. - I would actually like to rename `Param` to `Placeholder` to better reflect its use and get closer to Chalk, but I'll leave that to a follow-up. - introduce a context for type lowering, to allow lowering `impl Trait` to different things depending on where we are. And since we have that, we can also lower type parameters directly to variables instead of placeholders. Also, we'll be able to use this later to collect diagnostics. - implement argument position impl trait by lowering it to type parameters. I've realized that this is necessary to correctly implement it; e.g. consider `fn foo(impl Display) -> impl Something`. It's observable that the return type of e.g. `foo(1u32)` unifies with itself, but doesn't unify with e.g. `foo(1i32)`; so the return type needs to be parameterized by the argument type. This fixes a few bugs as well: - type parameters 'losing' their name when they go through Chalk, as mentioned above (i.e. getting `[missing name]` somewhere) - impl trait not being considered as implementing the super traits (very noticeable for the `db` in RA) - the fact that argument impl trait was only turned into variables when the function got called caused type mismatches when the function was used as a value (fixes a few type mismatches in RA) The one thing I'm not so happy with here is how we're lowering `impl Trait` types to variables; since `TypeRef`s don't have an identity currently, we just count how many of them we have seen while going through the function signature. That's quite fragile though, since we have to do it while desugaring generics and while lowering the type signature, and in the exact same order in both cases. We could consider either giving only `TypeRef::ImplTrait` a local id, or maybe just giving all `TypeRef`s an identity after all (we talked about this before)... Follow-up tasks: - handle return position impl trait; we basically need to create a variable and some trait obligations for that variable - rename `Param` to `Placeholder` Co-authored-by: Florian Diebold <[email protected]> Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_assists/src/handlers/add_new.rs14
-rw-r--r--crates/ra_hir/src/code_model.rs28
-rw-r--r--crates/ra_hir/src/source_analyzer.rs8
-rw-r--r--crates/ra_hir_def/src/generics.rs73
-rw-r--r--crates/ra_hir_def/src/resolver.rs10
-rw-r--r--crates/ra_hir_def/src/type_ref.rs42
-rw-r--r--crates/ra_hir_ty/src/db.rs34
-rw-r--r--crates/ra_hir_ty/src/infer.rs66
-rw-r--r--crates/ra_hir_ty/src/infer/coerce.rs18
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs24
-rw-r--r--crates/ra_hir_ty/src/infer/pat.rs7
-rw-r--r--crates/ra_hir_ty/src/infer/path.rs60
-rw-r--r--crates/ra_hir_ty/src/lib.rs262
-rw-r--r--crates/ra_hir_ty/src/lower.rs577
-rw-r--r--crates/ra_hir_ty/src/marks.rs1
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs6
-rw-r--r--crates/ra_hir_ty/src/tests/coercion.rs26
-rw-r--r--crates/ra_hir_ty/src/tests/method_resolution.rs48
-rw-r--r--crates/ra_hir_ty/src/tests/patterns.rs4
-rw-r--r--crates/ra_hir_ty/src/tests/regression.rs2
-rw-r--r--crates/ra_hir_ty/src/tests/simple.rs42
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs312
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs33
-rw-r--r--crates/ra_hir_ty/src/utils.rs91
24 files changed, 1174 insertions, 614 deletions
diff --git a/crates/ra_assists/src/handlers/add_new.rs b/crates/ra_assists/src/handlers/add_new.rs
index a08639311..2701eddb8 100644
--- a/crates/ra_assists/src/handlers/add_new.rs
+++ b/crates/ra_assists/src/handlers/add_new.rs
@@ -1,5 +1,5 @@
1use format_buf::format; 1use format_buf::format;
2use hir::InFile; 2use hir::{Adt, InFile};
3use join_to_string::join; 3use join_to_string::join;
4use ra_syntax::{ 4use ra_syntax::{
5 ast::{ 5 ast::{
@@ -135,16 +135,22 @@ fn find_struct_impl(ctx: &AssistCtx, strukt: &ast::StructDef) -> Option<Option<a
135 })?; 135 })?;
136 let mut sb = ctx.source_binder(); 136 let mut sb = ctx.source_binder();
137 137
138 let struct_ty = { 138 let struct_def = {
139 let src = InFile { file_id: ctx.frange.file_id.into(), value: strukt.clone() }; 139 let src = InFile { file_id: ctx.frange.file_id.into(), value: strukt.clone() };
140 sb.to_def(src)?.ty(db) 140 sb.to_def(src)?
141 }; 141 };
142 142
143 let block = module.descendants().filter_map(ast::ImplBlock::cast).find_map(|impl_blk| { 143 let block = module.descendants().filter_map(ast::ImplBlock::cast).find_map(|impl_blk| {
144 let src = InFile { file_id: ctx.frange.file_id.into(), value: impl_blk.clone() }; 144 let src = InFile { file_id: ctx.frange.file_id.into(), value: impl_blk.clone() };
145 let blk = sb.to_def(src)?; 145 let blk = sb.to_def(src)?;
146 146
147 let same_ty = blk.target_ty(db) == struct_ty; 147 // FIXME: handle e.g. `struct S<T>; impl<U> S<U> {}`
148 // (we currently use the wrong type parameter)
149 // also we wouldn't want to use e.g. `impl S<u32>`
150 let same_ty = match blk.target_ty(db).as_adt() {
151 Some(def) => def == Adt::Struct(struct_def),
152 None => false,
153 };
148 let not_trait_impl = blk.target_trait(db).is_none(); 154 let not_trait_impl = blk.target_trait(db).is_none();
149 155
150 if !(same_ty && not_trait_impl) { 156 if !(same_ty && not_trait_impl) {
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index eaacf8c9e..4d9641728 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -10,9 +10,9 @@ use hir_def::{
10 per_ns::PerNs, 10 per_ns::PerNs,
11 resolver::HasResolver, 11 resolver::HasResolver,
12 type_ref::{Mutability, TypeRef}, 12 type_ref::{Mutability, TypeRef},
13 AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId, 13 AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId,
14 LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, 14 LocalEnumVariantId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId,
15 TypeParamId, UnionId, 15 TraitId, TypeAliasId, TypeParamId, UnionId,
16}; 16};
17use hir_expand::{ 17use hir_expand::{
18 diagnostics::DiagnosticSink, 18 diagnostics::DiagnosticSink,
@@ -21,7 +21,7 @@ use hir_expand::{
21}; 21};
22use hir_ty::{ 22use hir_ty::{
23 autoderef, display::HirFormatter, expr::ExprValidator, method_resolution, ApplicationTy, 23 autoderef, display::HirFormatter, expr::ExprValidator, method_resolution, ApplicationTy,
24 Canonical, InEnvironment, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, 24 Canonical, InEnvironment, Substs, TraitEnvironment, Ty, TyDefId, TypeCtor,
25}; 25};
26use ra_db::{CrateId, Edition, FileId}; 26use ra_db::{CrateId, Edition, FileId};
27use ra_prof::profile; 27use ra_prof::profile;
@@ -270,7 +270,13 @@ impl StructField {
270 270
271 pub fn ty(&self, db: &impl HirDatabase) -> Type { 271 pub fn ty(&self, db: &impl HirDatabase) -> Type {
272 let var_id = self.parent.into(); 272 let var_id = self.parent.into();
273 let ty = db.field_types(var_id)[self.id].clone(); 273 let generic_def_id: GenericDefId = match self.parent {
274 VariantDef::Struct(it) => it.id.into(),
275 VariantDef::Union(it) => it.id.into(),
276 VariantDef::EnumVariant(it) => it.parent.id.into(),
277 };
278 let substs = Substs::type_params(db, generic_def_id);
279 let ty = db.field_types(var_id)[self.id].clone().subst(&substs);
274 Type::new(db, self.parent.module(db).id.krate.into(), var_id, ty) 280 Type::new(db, self.parent.module(db).id.krate.into(), var_id, ty)
275 } 281 }
276 282
@@ -755,7 +761,7 @@ pub struct TypeParam {
755impl TypeParam { 761impl TypeParam {
756 pub fn name(self, db: &impl HirDatabase) -> Name { 762 pub fn name(self, db: &impl HirDatabase) -> Name {
757 let params = db.generic_params(self.id.parent); 763 let params = db.generic_params(self.id.parent);
758 params.types[self.id.local_id].name.clone() 764 params.types[self.id.local_id].name.clone().unwrap_or_else(Name::missing)
759 } 765 }
760 766
761 pub fn module(self, db: &impl HirDatabase) -> Module { 767 pub fn module(self, db: &impl HirDatabase) -> Module {
@@ -789,8 +795,9 @@ impl ImplBlock {
789 pub fn target_ty(&self, db: &impl HirDatabase) -> Type { 795 pub fn target_ty(&self, db: &impl HirDatabase) -> Type {
790 let impl_data = db.impl_data(self.id); 796 let impl_data = db.impl_data(self.id);
791 let resolver = self.id.resolver(db); 797 let resolver = self.id.resolver(db);
798 let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
792 let environment = TraitEnvironment::lower(db, &resolver); 799 let environment = TraitEnvironment::lower(db, &resolver);
793 let ty = Ty::from_hir(db, &resolver, &impl_data.target_type); 800 let ty = Ty::from_hir(&ctx, &impl_data.target_type);
794 Type { 801 Type {
795 krate: self.id.lookup(db).container.module(db).krate, 802 krate: self.id.lookup(db).container.module(db).krate,
796 ty: InEnvironment { value: ty, environment }, 803 ty: InEnvironment { value: ty, environment },
@@ -851,9 +858,10 @@ impl Type {
851 fn from_def( 858 fn from_def(
852 db: &impl HirDatabase, 859 db: &impl HirDatabase,
853 krate: CrateId, 860 krate: CrateId,
854 def: impl HasResolver + Into<TyDefId>, 861 def: impl HasResolver + Into<TyDefId> + Into<GenericDefId>,
855 ) -> Type { 862 ) -> Type {
856 let ty = db.ty(def.into()); 863 let substs = Substs::type_params(db, def);
864 let ty = db.ty(def.into()).subst(&substs);
857 Type::new(db, krate, def, ty) 865 Type::new(db, krate, def, ty)
858 } 866 }
859 867
@@ -950,7 +958,7 @@ impl Type {
950 match a_ty.ctor { 958 match a_ty.ctor {
951 TypeCtor::Tuple { .. } => { 959 TypeCtor::Tuple { .. } => {
952 for ty in a_ty.parameters.iter() { 960 for ty in a_ty.parameters.iter() {
953 let ty = ty.clone().subst(&a_ty.parameters); 961 let ty = ty.clone();
954 res.push(self.derived(ty)); 962 res.push(self.derived(ty));
955 } 963 }
956 } 964 }
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs
index 4f8fc9602..bb9a35c5d 100644
--- a/crates/ra_hir/src/source_analyzer.rs
+++ b/crates/ra_hir/src/source_analyzer.rs
@@ -178,6 +178,10 @@ impl SourceAnalyzer {
178 } 178 }
179 } 179 }
180 180
181 fn trait_env(&self, db: &impl HirDatabase) -> Arc<TraitEnvironment> {
182 TraitEnvironment::lower(db, &self.resolver)
183 }
184
181 pub fn type_of(&self, db: &impl HirDatabase, expr: &ast::Expr) -> Option<Type> { 185 pub fn type_of(&self, db: &impl HirDatabase, expr: &ast::Expr) -> Option<Type> {
182 let expr_id = if let Some(expr) = self.expand_expr(db, InFile::new(self.file_id, expr)) { 186 let expr_id = if let Some(expr) = self.expand_expr(db, InFile::new(self.file_id, expr)) {
183 self.body_source_map.as_ref()?.node_expr(expr.as_ref())? 187 self.body_source_map.as_ref()?.node_expr(expr.as_ref())?
@@ -186,14 +190,14 @@ impl SourceAnalyzer {
186 }; 190 };
187 191
188 let ty = self.infer.as_ref()?[expr_id].clone(); 192 let ty = self.infer.as_ref()?[expr_id].clone();
189 let environment = TraitEnvironment::lower(db, &self.resolver); 193 let environment = self.trait_env(db);
190 Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } }) 194 Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } })
191 } 195 }
192 196
193 pub fn type_of_pat(&self, db: &impl HirDatabase, pat: &ast::Pat) -> Option<Type> { 197 pub fn type_of_pat(&self, db: &impl HirDatabase, pat: &ast::Pat) -> Option<Type> {
194 let pat_id = self.pat_id(pat)?; 198 let pat_id = self.pat_id(pat)?;
195 let ty = self.infer.as_ref()?[pat_id].clone(); 199 let ty = self.infer.as_ref()?[pat_id].clone();
196 let environment = TraitEnvironment::lower(db, &self.resolver); 200 let environment = self.trait_env(db);
197 Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } }) 201 Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } })
198 } 202 }
199 203
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index e9c28c730..f765e6edc 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -27,8 +27,16 @@ use crate::{
27/// Data about a generic parameter (to a function, struct, impl, ...). 27/// Data about a generic parameter (to a function, struct, impl, ...).
28#[derive(Clone, PartialEq, Eq, Debug)] 28#[derive(Clone, PartialEq, Eq, Debug)]
29pub struct TypeParamData { 29pub struct TypeParamData {
30 pub name: Name, 30 pub name: Option<Name>,
31 pub default: Option<TypeRef>, 31 pub default: Option<TypeRef>,
32 pub provenance: TypeParamProvenance,
33}
34
35#[derive(Copy, Clone, PartialEq, Eq, Debug)]
36pub enum TypeParamProvenance {
37 TypeParamList,
38 TraitSelf,
39 ArgumentImplTrait,
32} 40}
33 41
34/// Data about the generic parameters of a function, struct, impl, etc. 42/// Data about the generic parameters of a function, struct, impl, etc.
@@ -45,10 +53,17 @@ pub struct GenericParams {
45/// associated type bindings like `Iterator<Item = u32>`. 53/// associated type bindings like `Iterator<Item = u32>`.
46#[derive(Clone, PartialEq, Eq, Debug)] 54#[derive(Clone, PartialEq, Eq, Debug)]
47pub struct WherePredicate { 55pub struct WherePredicate {
48 pub type_ref: TypeRef, 56 pub target: WherePredicateTarget,
49 pub bound: TypeBound, 57 pub bound: TypeBound,
50} 58}
51 59
60#[derive(Clone, PartialEq, Eq, Debug)]
61pub enum WherePredicateTarget {
62 TypeRef(TypeRef),
63 /// For desugared where predicates that can directly refer to a type param.
64 TypeParam(LocalTypeParamId),
65}
66
52type SourceMap = ArenaMap<LocalTypeParamId, Either<ast::TraitDef, ast::TypeParam>>; 67type SourceMap = ArenaMap<LocalTypeParamId, Either<ast::TraitDef, ast::TypeParam>>;
53 68
54impl GenericParams { 69impl GenericParams {
@@ -68,6 +83,11 @@ impl GenericParams {
68 GenericDefId::FunctionId(it) => { 83 GenericDefId::FunctionId(it) => {
69 let src = it.lookup(db).source(db); 84 let src = it.lookup(db).source(db);
70 generics.fill(&mut sm, &src.value); 85 generics.fill(&mut sm, &src.value);
86 // lower `impl Trait` in arguments
87 let data = db.function_data(it);
88 for param in &data.params {
89 generics.fill_implicit_impl_trait_args(param);
90 }
71 src.file_id 91 src.file_id
72 } 92 }
73 GenericDefId::AdtId(AdtId::StructId(it)) => { 93 GenericDefId::AdtId(AdtId::StructId(it)) => {
@@ -89,8 +109,11 @@ impl GenericParams {
89 let src = it.lookup(db).source(db); 109 let src = it.lookup(db).source(db);
90 110
91 // traits get the Self type as an implicit first type parameter 111 // traits get the Self type as an implicit first type parameter
92 let self_param_id = 112 let self_param_id = generics.types.alloc(TypeParamData {
93 generics.types.alloc(TypeParamData { name: name![Self], default: None }); 113 name: Some(name![Self]),
114 default: None,
115 provenance: TypeParamProvenance::TraitSelf,
116 });
94 sm.insert(self_param_id, Either::Left(src.value.clone())); 117 sm.insert(self_param_id, Either::Left(src.value.clone()));
95 // add super traits as bounds on Self 118 // add super traits as bounds on Self
96 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar 119 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
@@ -142,7 +165,11 @@ impl GenericParams {
142 let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); 165 let name = type_param.name().map_or_else(Name::missing, |it| it.as_name());
143 // FIXME: Use `Path::from_src` 166 // FIXME: Use `Path::from_src`
144 let default = type_param.default_type().map(TypeRef::from_ast); 167 let default = type_param.default_type().map(TypeRef::from_ast);
145 let param = TypeParamData { name: name.clone(), default }; 168 let param = TypeParamData {
169 name: Some(name.clone()),
170 default,
171 provenance: TypeParamProvenance::TypeParamList,
172 };
146 let param_id = self.types.alloc(param); 173 let param_id = self.types.alloc(param);
147 sm.insert(param_id, Either::Right(type_param.clone())); 174 sm.insert(param_id, Either::Right(type_param.clone()));
148 175
@@ -170,11 +197,43 @@ impl GenericParams {
170 return; 197 return;
171 } 198 }
172 let bound = TypeBound::from_ast(bound); 199 let bound = TypeBound::from_ast(bound);
173 self.where_predicates.push(WherePredicate { type_ref, bound }); 200 self.where_predicates
201 .push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound });
202 }
203
204 fn fill_implicit_impl_trait_args(&mut self, type_ref: &TypeRef) {
205 type_ref.walk(&mut |type_ref| {
206 if let TypeRef::ImplTrait(bounds) = type_ref {
207 let param = TypeParamData {
208 name: None,
209 default: None,
210 provenance: TypeParamProvenance::ArgumentImplTrait,
211 };
212 let param_id = self.types.alloc(param);
213 for bound in bounds {
214 self.where_predicates.push(WherePredicate {
215 target: WherePredicateTarget::TypeParam(param_id),
216 bound: bound.clone(),
217 });
218 }
219 }
220 });
174 } 221 }
175 222
176 pub fn find_by_name(&self, name: &Name) -> Option<LocalTypeParamId> { 223 pub fn find_by_name(&self, name: &Name) -> Option<LocalTypeParamId> {
177 self.types.iter().find_map(|(id, p)| if &p.name == name { Some(id) } else { None }) 224 self.types
225 .iter()
226 .find_map(|(id, p)| if p.name.as_ref() == Some(name) { Some(id) } else { None })
227 }
228
229 pub fn find_trait_self_param(&self) -> Option<LocalTypeParamId> {
230 self.types.iter().find_map(|(id, p)| {
231 if p.provenance == TypeParamProvenance::TraitSelf {
232 Some(id)
233 } else {
234 None
235 }
236 })
178 } 237 }
179} 238}
180 239
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index f7bac5801..05cf4646a 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -490,10 +490,12 @@ impl Scope {
490 } 490 }
491 Scope::GenericParams { params, def } => { 491 Scope::GenericParams { params, def } => {
492 for (local_id, param) in params.types.iter() { 492 for (local_id, param) in params.types.iter() {
493 f( 493 if let Some(name) = &param.name {
494 param.name.clone(), 494 f(
495 ScopeDef::GenericParam(TypeParamId { local_id, parent: *def }), 495 name.clone(),
496 ) 496 ScopeDef::GenericParam(TypeParamId { local_id, parent: *def }),
497 )
498 }
497 } 499 }
498 } 500 }
499 Scope::ImplBlockScope(i) => { 501 Scope::ImplBlockScope(i) => {
diff --git a/crates/ra_hir_def/src/type_ref.rs b/crates/ra_hir_def/src/type_ref.rs
index 5f10e9a88..102fdb13d 100644
--- a/crates/ra_hir_def/src/type_ref.rs
+++ b/crates/ra_hir_def/src/type_ref.rs
@@ -124,6 +124,48 @@ impl TypeRef {
124 pub(crate) fn unit() -> TypeRef { 124 pub(crate) fn unit() -> TypeRef {
125 TypeRef::Tuple(Vec::new()) 125 TypeRef::Tuple(Vec::new())
126 } 126 }
127
128 pub fn walk(&self, f: &mut impl FnMut(&TypeRef)) {
129 go(self, f);
130
131 fn go(type_ref: &TypeRef, f: &mut impl FnMut(&TypeRef)) {
132 f(type_ref);
133 match type_ref {
134 TypeRef::Fn(types) | TypeRef::Tuple(types) => types.iter().for_each(|t| go(t, f)),
135 TypeRef::RawPtr(type_ref, _)
136 | TypeRef::Reference(type_ref, _)
137 | TypeRef::Array(type_ref)
138 | TypeRef::Slice(type_ref) => go(&type_ref, f),
139 TypeRef::ImplTrait(bounds) | TypeRef::DynTrait(bounds) => {
140 for bound in bounds {
141 match bound {
142 TypeBound::Path(path) => go_path(path, f),
143 TypeBound::Error => (),
144 }
145 }
146 }
147 TypeRef::Path(path) => go_path(path, f),
148 TypeRef::Never | TypeRef::Placeholder | TypeRef::Error => {}
149 };
150 }
151
152 fn go_path(path: &Path, f: &mut impl FnMut(&TypeRef)) {
153 if let Some(type_ref) = path.type_anchor() {
154 go(type_ref, f);
155 }
156 for segment in path.segments().iter() {
157 if let Some(args_and_bindings) = segment.args_and_bindings {
158 for arg in &args_and_bindings.args {
159 let crate::path::GenericArg::Type(type_ref) = arg;
160 go(type_ref, f);
161 }
162 for (_, type_ref) in &args_and_bindings.bindings {
163 go(type_ref, f);
164 }
165 }
166 }
167 }
168 }
127} 169}
128 170
129pub(crate) fn type_bounds_from_ast(type_bounds_opt: Option<ast::TypeBoundList>) -> Vec<TypeBound> { 171pub(crate) fn type_bounds_from_ast(type_bounds_opt: Option<ast::TypeBoundList>) -> Vec<TypeBound> {
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs
index eb521c7a0..e9bfcfa17 100644
--- a/crates/ra_hir_ty/src/db.rs
+++ b/crates/ra_hir_ty/src/db.rs
@@ -3,17 +3,18 @@
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::{ 5use hir_def::{
6 db::DefDatabase, DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId, 6 db::DefDatabase, DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, TypeParamId,
7 VariantId,
7}; 8};
8use ra_arena::map::ArenaMap; 9use ra_arena::map::ArenaMap;
9use ra_db::{salsa, CrateId}; 10use ra_db::{impl_intern_key, salsa, CrateId};
10use ra_prof::profile; 11use ra_prof::profile;
11 12
12use crate::{ 13use crate::{
13 method_resolution::CrateImplBlocks, 14 method_resolution::CrateImplBlocks,
14 traits::{chalk, AssocTyValue, Impl}, 15 traits::{chalk, AssocTyValue, Impl},
15 CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, TraitRef, Ty, TyDefId, TypeCtor, 16 Binders, CallableDef, GenericPredicate, InferenceResult, PolyFnSig, Substs, TraitRef, Ty,
16 ValueTyDefId, 17 TyDefId, TypeCtor, ValueTyDefId,
17}; 18};
18 19
19#[salsa::query_group(HirDatabaseStorage)] 20#[salsa::query_group(HirDatabaseStorage)]
@@ -27,34 +28,33 @@ pub trait HirDatabase: DefDatabase {
27 28
28 #[salsa::invoke(crate::lower::ty_query)] 29 #[salsa::invoke(crate::lower::ty_query)]
29 #[salsa::cycle(crate::lower::ty_recover)] 30 #[salsa::cycle(crate::lower::ty_recover)]
30 fn ty(&self, def: TyDefId) -> Ty; 31 fn ty(&self, def: TyDefId) -> Binders<Ty>;
31 32
32 #[salsa::invoke(crate::lower::value_ty_query)] 33 #[salsa::invoke(crate::lower::value_ty_query)]
33 fn value_ty(&self, def: ValueTyDefId) -> Ty; 34 fn value_ty(&self, def: ValueTyDefId) -> Binders<Ty>;
34 35
35 #[salsa::invoke(crate::lower::impl_self_ty_query)] 36 #[salsa::invoke(crate::lower::impl_self_ty_query)]
36 #[salsa::cycle(crate::lower::impl_self_ty_recover)] 37 #[salsa::cycle(crate::lower::impl_self_ty_recover)]
37 fn impl_self_ty(&self, def: ImplId) -> Ty; 38 fn impl_self_ty(&self, def: ImplId) -> Binders<Ty>;
38 39
39 #[salsa::invoke(crate::lower::impl_trait_query)] 40 #[salsa::invoke(crate::lower::impl_trait_query)]
40 fn impl_trait(&self, def: ImplId) -> Option<TraitRef>; 41 fn impl_trait(&self, def: ImplId) -> Option<Binders<TraitRef>>;
41 42
42 #[salsa::invoke(crate::lower::field_types_query)] 43 #[salsa::invoke(crate::lower::field_types_query)]
43 fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>; 44 fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Binders<Ty>>>;
44 45
45 #[salsa::invoke(crate::callable_item_sig)] 46 #[salsa::invoke(crate::callable_item_sig)]
46 fn callable_item_signature(&self, def: CallableDef) -> FnSig; 47 fn callable_item_signature(&self, def: CallableDef) -> PolyFnSig;
47 48
48 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)] 49 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
49 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)] 50 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)]
50 fn generic_predicates_for_param( 51 fn generic_predicates_for_param(
51 &self, 52 &self,
52 def: GenericDefId, 53 param_id: TypeParamId,
53 param_idx: u32, 54 ) -> Arc<[Binders<GenericPredicate>]>;
54 ) -> Arc<[GenericPredicate]>;
55 55
56 #[salsa::invoke(crate::lower::generic_predicates_query)] 56 #[salsa::invoke(crate::lower::generic_predicates_query)]
57 fn generic_predicates(&self, def: GenericDefId) -> Arc<[GenericPredicate]>; 57 fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>;
58 58
59 #[salsa::invoke(crate::lower::generic_defaults_query)] 59 #[salsa::invoke(crate::lower::generic_defaults_query)]
60 fn generic_defaults(&self, def: GenericDefId) -> Substs; 60 fn generic_defaults(&self, def: GenericDefId) -> Substs;
@@ -77,6 +77,8 @@ pub trait HirDatabase: DefDatabase {
77 #[salsa::interned] 77 #[salsa::interned]
78 fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::TypeCtorId; 78 fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::TypeCtorId;
79 #[salsa::interned] 79 #[salsa::interned]
80 fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId;
81 #[salsa::interned]
80 fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId; 82 fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId;
81 #[salsa::interned] 83 #[salsa::interned]
82 fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId; 84 fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId;
@@ -117,3 +119,7 @@ fn infer(db: &impl HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
117fn hir_database_is_object_safe() { 119fn hir_database_is_object_safe() {
118 fn _assert_object_safe(_: &dyn HirDatabase) {} 120 fn _assert_object_safe(_: &dyn HirDatabase) {}
119} 121}
122
123#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
124pub struct GlobalTypeParamId(salsa::InternId);
125impl_intern_key!(GlobalTypeParamId);
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index e2eda3134..a9d958c8b 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -34,7 +34,6 @@ use hir_expand::{diagnostics::DiagnosticSink, name::name};
34use ra_arena::map::ArenaMap; 34use ra_arena::map::ArenaMap;
35use ra_prof::profile; 35use ra_prof::profile;
36use ra_syntax::SmolStr; 36use ra_syntax::SmolStr;
37use test_utils::tested_by;
38 37
39use super::{ 38use super::{
40 primitive::{FloatTy, IntTy}, 39 primitive::{FloatTy, IntTy},
@@ -42,7 +41,9 @@ use super::{
42 ApplicationTy, GenericPredicate, InEnvironment, ProjectionTy, Substs, TraitEnvironment, 41 ApplicationTy, GenericPredicate, InEnvironment, ProjectionTy, Substs, TraitEnvironment,
43 TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, 42 TraitRef, Ty, TypeCtor, TypeWalk, Uncertain,
44}; 43};
45use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic}; 44use crate::{
45 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
46};
46 47
47pub(crate) use unify::unify; 48pub(crate) use unify::unify;
48 49
@@ -271,38 +272,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
271 self.result.diagnostics.push(diagnostic); 272 self.result.diagnostics.push(diagnostic);
272 } 273 }
273 274
274 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty { 275 fn make_ty_with_mode(
275 let ty = Ty::from_hir( 276 &mut self,
276 self.db, 277 type_ref: &TypeRef,
277 // FIXME use right resolver for block 278 impl_trait_mode: ImplTraitLoweringMode,
278 &self.resolver, 279 ) -> Ty {
279 type_ref, 280 // FIXME use right resolver for block
280 ); 281 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
282 .with_impl_trait_mode(impl_trait_mode);
283 let ty = Ty::from_hir(&ctx, type_ref);
281 let ty = self.insert_type_vars(ty); 284 let ty = self.insert_type_vars(ty);
282 self.normalize_associated_types_in(ty) 285 self.normalize_associated_types_in(ty)
283 } 286 }
284 287
285 /// Replaces `impl Trait` in `ty` by type variables and obligations for 288 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
286 /// those variables. This is done for function arguments when calling a 289 self.make_ty_with_mode(type_ref, ImplTraitLoweringMode::Disallowed)
287 /// function, and for return types when inside the function body, i.e. in
288 /// the cases where the `impl Trait` is 'transparent'. In other cases, `impl
289 /// Trait` is represented by `Ty::Opaque`.
290 fn insert_vars_for_impl_trait(&mut self, ty: Ty) -> Ty {
291 ty.fold(&mut |ty| match ty {
292 Ty::Opaque(preds) => {
293 tested_by!(insert_vars_for_impl_trait);
294 let var = self.table.new_type_var();
295 let var_subst = Substs::builder(1).push(var.clone()).build();
296 self.obligations.extend(
297 preds
298 .iter()
299 .map(|pred| pred.clone().subst_bound_vars(&var_subst))
300 .filter_map(Obligation::from_predicate),
301 );
302 var
303 }
304 _ => ty,
305 })
306 } 290 }
307 291
308 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. 292 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it.
@@ -446,19 +430,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
446 None => return (Ty::Unknown, None), 430 None => return (Ty::Unknown, None),
447 }; 431 };
448 let resolver = &self.resolver; 432 let resolver = &self.resolver;
433 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
449 // FIXME: this should resolve assoc items as well, see this example: 434 // FIXME: this should resolve assoc items as well, see this example:
450 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 435 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521
451 match resolver.resolve_path_in_type_ns_fully(self.db, path.mod_path()) { 436 match resolver.resolve_path_in_type_ns_fully(self.db, path.mod_path()) {
452 Some(TypeNs::AdtId(AdtId::StructId(strukt))) => { 437 Some(TypeNs::AdtId(AdtId::StructId(strukt))) => {
453 let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into()); 438 let substs = Ty::substs_from_path(&ctx, path, strukt.into());
454 let ty = self.db.ty(strukt.into()); 439 let ty = self.db.ty(strukt.into());
455 let ty = self.insert_type_vars(ty.apply_substs(substs)); 440 let ty = self.insert_type_vars(ty.subst(&substs));
456 (ty, Some(strukt.into())) 441 (ty, Some(strukt.into()))
457 } 442 }
458 Some(TypeNs::EnumVariantId(var)) => { 443 Some(TypeNs::EnumVariantId(var)) => {
459 let substs = Ty::substs_from_path(self.db, resolver, path, var.into()); 444 let substs = Ty::substs_from_path(&ctx, path, var.into());
460 let ty = self.db.ty(var.parent.into()); 445 let ty = self.db.ty(var.parent.into());
461 let ty = self.insert_type_vars(ty.apply_substs(substs)); 446 let ty = self.insert_type_vars(ty.subst(&substs));
462 (ty, Some(var.into())) 447 (ty, Some(var.into()))
463 } 448 }
464 Some(_) | None => (Ty::Unknown, None), 449 Some(_) | None => (Ty::Unknown, None),
@@ -471,13 +456,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
471 456
472 fn collect_fn(&mut self, data: &FunctionData) { 457 fn collect_fn(&mut self, data: &FunctionData) {
473 let body = Arc::clone(&self.body); // avoid borrow checker problem 458 let body = Arc::clone(&self.body); // avoid borrow checker problem
474 for (type_ref, pat) in data.params.iter().zip(body.params.iter()) { 459 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
475 let ty = self.make_ty(type_ref); 460 .with_impl_trait_mode(ImplTraitLoweringMode::Param);
461 let param_tys =
462 data.params.iter().map(|type_ref| Ty::from_hir(&ctx, type_ref)).collect::<Vec<_>>();
463 for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) {
464 let ty = self.insert_type_vars(ty);
465 let ty = self.normalize_associated_types_in(ty);
476 466
477 self.infer_pat(*pat, &ty, BindingMode::default()); 467 self.infer_pat(*pat, &ty, BindingMode::default());
478 } 468 }
479 let return_ty = self.make_ty(&data.ret_type); 469 let return_ty = self.make_ty_with_mode(&data.ret_type, ImplTraitLoweringMode::Disallowed); // FIXME implement RPIT
480 self.return_ty = self.insert_vars_for_impl_trait(return_ty); 470 self.return_ty = return_ty;
481 } 471 }
482 472
483 fn infer_body(&mut self) { 473 fn infer_body(&mut self) {
diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs
index 83c0c2c3f..f68a1439f 100644
--- a/crates/ra_hir_ty/src/infer/coerce.rs
+++ b/crates/ra_hir_ty/src/infer/coerce.rs
@@ -57,8 +57,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
57 let trait_ref = db.impl_trait(impl_id)?; 57 let trait_ref = db.impl_trait(impl_id)?;
58 58
59 // `CoerseUnsized` has one generic parameter for the target type. 59 // `CoerseUnsized` has one generic parameter for the target type.
60 let cur_from_ty = trait_ref.substs.0.get(0)?; 60 let cur_from_ty = trait_ref.value.substs.0.get(0)?;
61 let cur_to_ty = trait_ref.substs.0.get(1)?; 61 let cur_to_ty = trait_ref.value.substs.0.get(1)?;
62 62
63 match (&cur_from_ty, cur_to_ty) { 63 match (&cur_from_ty, cur_to_ty) {
64 (ty_app!(ctor1, st1), ty_app!(ctor2, st2)) => { 64 (ty_app!(ctor1, st1), ty_app!(ctor2, st2)) => {
@@ -66,9 +66,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
66 // This works for smart-pointer-like coercion, which covers all impls from std. 66 // This works for smart-pointer-like coercion, which covers all impls from std.
67 st1.iter().zip(st2.iter()).enumerate().find_map(|(i, (ty1, ty2))| { 67 st1.iter().zip(st2.iter()).enumerate().find_map(|(i, (ty1, ty2))| {
68 match (ty1, ty2) { 68 match (ty1, ty2) {
69 (Ty::Param { idx: p1, .. }, Ty::Param { idx: p2, .. }) 69 (Ty::Bound(idx1), Ty::Bound(idx2)) if idx1 != idx2 => {
70 if p1 != p2 =>
71 {
72 Some(((*ctor1, *ctor2), i)) 70 Some(((*ctor1, *ctor2), i))
73 } 71 }
74 _ => None, 72 _ => None,
@@ -256,8 +254,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
256 let unsize_generic_index = { 254 let unsize_generic_index = {
257 let mut index = None; 255 let mut index = None;
258 let mut multiple_param = false; 256 let mut multiple_param = false;
259 field_tys[last_field_id].walk(&mut |ty| match ty { 257 field_tys[last_field_id].value.walk(&mut |ty| match ty {
260 &Ty::Param { idx, .. } => { 258 &Ty::Bound(idx) => {
261 if index.is_none() { 259 if index.is_none() {
262 index = Some(idx); 260 index = Some(idx);
263 } else if Some(idx) != index { 261 } else if Some(idx) != index {
@@ -276,10 +274,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
276 // Check other fields do not involve it. 274 // Check other fields do not involve it.
277 let mut multiple_used = false; 275 let mut multiple_used = false;
278 fields.for_each(|(field_id, _data)| { 276 fields.for_each(|(field_id, _data)| {
279 field_tys[field_id].walk(&mut |ty| match ty { 277 field_tys[field_id].value.walk(&mut |ty| match ty {
280 &Ty::Param { idx, .. } if idx == unsize_generic_index => { 278 &Ty::Bound(idx) if idx == unsize_generic_index => multiple_used = true,
281 multiple_used = true
282 }
283 _ => {} 279 _ => {}
284 }) 280 })
285 }); 281 });
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index 31259a01d..3c9c02d03 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -10,7 +10,7 @@ use hir_def::{
10 resolver::resolver_for_expr, 10 resolver::resolver_for_expr,
11 AdtId, AssocContainerId, Lookup, StructFieldId, 11 AdtId, AssocContainerId, Lookup, StructFieldId,
12}; 12};
13use hir_expand::name::{name, Name}; 13use hir_expand::name::Name;
14use ra_syntax::ast::RangeOp; 14use ra_syntax::ast::RangeOp;
15 15
16use crate::{ 16use crate::{
@@ -19,8 +19,8 @@ use crate::{
19 method_resolution, op, 19 method_resolution, op,
20 traits::InEnvironment, 20 traits::InEnvironment,
21 utils::{generics, variant_data, Generics}, 21 utils::{generics, variant_data, Generics},
22 ApplicationTy, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, Ty, 22 ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef,
23 TypeCtor, TypeWalk, Uncertain, 23 Ty, TypeCtor, Uncertain,
24}; 24};
25 25
26use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; 26use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch};
@@ -236,8 +236,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
236 self.result.record_field_resolutions.insert(field.expr, field_def); 236 self.result.record_field_resolutions.insert(field.expr, field_def);
237 } 237 }
238 let field_ty = field_def 238 let field_ty = field_def
239 .map_or(Ty::Unknown, |it| field_types[it.local_id].clone()) 239 .map_or(Ty::Unknown, |it| field_types[it.local_id].clone().subst(&substs));
240 .subst(&substs);
241 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 240 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
242 } 241 }
243 if let Some(expr) = spread { 242 if let Some(expr) = spread {
@@ -588,10 +587,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
588 self.write_method_resolution(tgt_expr, func); 587 self.write_method_resolution(tgt_expr, func);
589 (ty, self.db.value_ty(func.into()), Some(generics(self.db, func.into()))) 588 (ty, self.db.value_ty(func.into()), Some(generics(self.db, func.into())))
590 } 589 }
591 None => (receiver_ty, Ty::Unknown, None), 590 None => (receiver_ty, Binders::new(0, Ty::Unknown), None),
592 }; 591 };
593 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); 592 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
594 let method_ty = method_ty.apply_substs(substs); 593 let method_ty = method_ty.subst(&substs);
595 let method_ty = self.insert_type_vars(method_ty); 594 let method_ty = self.insert_type_vars(method_ty);
596 self.register_obligations_for_call(&method_ty); 595 self.register_obligations_for_call(&method_ty);
597 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { 596 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) {
@@ -635,7 +634,6 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
635 continue; 634 continue;
636 } 635 }
637 636
638 let param_ty = self.insert_vars_for_impl_trait(param_ty);
639 let param_ty = self.normalize_associated_types_in(param_ty); 637 let param_ty = self.normalize_associated_types_in(param_ty);
640 self.infer_expr_coerce(arg, &Expectation::has_type(param_ty.clone())); 638 self.infer_expr_coerce(arg, &Expectation::has_type(param_ty.clone()));
641 } 639 }
@@ -648,13 +646,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
648 generic_args: Option<&GenericArgs>, 646 generic_args: Option<&GenericArgs>,
649 receiver_ty: &Ty, 647 receiver_ty: &Ty,
650 ) -> Substs { 648 ) -> Substs {
651 let (total_len, _parent_len, child_len) = 649 let (parent_params, self_params, type_params, impl_trait_params) =
652 def_generics.as_ref().map_or((0, 0, 0), |g| g.len_split()); 650 def_generics.as_ref().map_or((0, 0, 0, 0), |g| g.provenance_split());
651 assert_eq!(self_params, 0); // method shouldn't have another Self param
652 let total_len = parent_params + type_params + impl_trait_params;
653 let mut substs = Vec::with_capacity(total_len); 653 let mut substs = Vec::with_capacity(total_len);
654 // Parent arguments are unknown, except for the receiver type 654 // Parent arguments are unknown, except for the receiver type
655 if let Some(parent_generics) = def_generics.as_ref().map(|p| p.iter_parent()) { 655 if let Some(parent_generics) = def_generics.as_ref().map(|p| p.iter_parent()) {
656 for (_id, param) in parent_generics { 656 for (_id, param) in parent_generics {
657 if param.name == name![Self] { 657 if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf {
658 substs.push(receiver_ty.clone()); 658 substs.push(receiver_ty.clone());
659 } else { 659 } else {
660 substs.push(Ty::Unknown); 660 substs.push(Ty::Unknown);
@@ -664,7 +664,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
664 // handle provided type arguments 664 // handle provided type arguments
665 if let Some(generic_args) = generic_args { 665 if let Some(generic_args) = generic_args {
666 // if args are provided, it should be all of them, but we can't rely on that 666 // if args are provided, it should be all of them, but we can't rely on that
667 for arg in generic_args.args.iter().take(child_len) { 667 for arg in generic_args.args.iter().take(type_params) {
668 match arg { 668 match arg {
669 GenericArg::Type(type_ref) => { 669 GenericArg::Type(type_ref) => {
670 let ty = self.make_ty(type_ref); 670 let ty = self.make_ty(type_ref);
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs
index a14662884..e7283f24c 100644
--- a/crates/ra_hir_ty/src/infer/pat.rs
+++ b/crates/ra_hir_ty/src/infer/pat.rs
@@ -12,7 +12,7 @@ use hir_expand::name::Name;
12use test_utils::tested_by; 12use test_utils::tested_by;
13 13
14use super::{BindingMode, InferenceContext}; 14use super::{BindingMode, InferenceContext};
15use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor, TypeWalk}; 15use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor};
16 16
17impl<'a, D: HirDatabase> InferenceContext<'a, D> { 17impl<'a, D: HirDatabase> InferenceContext<'a, D> {
18 fn infer_tuple_struct_pat( 18 fn infer_tuple_struct_pat(
@@ -34,8 +34,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
34 let expected_ty = var_data 34 let expected_ty = var_data
35 .as_ref() 35 .as_ref()
36 .and_then(|d| d.field(&Name::new_tuple_field(i))) 36 .and_then(|d| d.field(&Name::new_tuple_field(i)))
37 .map_or(Ty::Unknown, |field| field_tys[field].clone()) 37 .map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs));
38 .subst(&substs);
39 let expected_ty = self.normalize_associated_types_in(expected_ty); 38 let expected_ty = self.normalize_associated_types_in(expected_ty);
40 self.infer_pat(subpat, &expected_ty, default_bm); 39 self.infer_pat(subpat, &expected_ty, default_bm);
41 } 40 }
@@ -65,7 +64,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
65 for subpat in subpats { 64 for subpat in subpats {
66 let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); 65 let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name));
67 let expected_ty = 66 let expected_ty =
68 matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone()).subst(&substs); 67 matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs));
69 let expected_ty = self.normalize_associated_types_in(expected_ty); 68 let expected_ty = self.normalize_associated_types_in(expected_ty);
70 self.infer_pat(subpat.pat, &expected_ty, default_bm); 69 self.infer_pat(subpat.pat, &expected_ty, default_bm);
71 } 70 }
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs
index 2c1d4831d..686ce7a21 100644
--- a/crates/ra_hir_ty/src/infer/path.rs
+++ b/crates/ra_hir_ty/src/infer/path.rs
@@ -9,9 +9,9 @@ use hir_def::{
9}; 9};
10use hir_expand::name::Name; 10use hir_expand::name::Name;
11 11
12use crate::{db::HirDatabase, method_resolution, Substs, Ty, TypeWalk, ValueTyDefId}; 12use crate::{db::HirDatabase, method_resolution, Substs, Ty, ValueTyDefId};
13 13
14use super::{ExprOrPatId, InferenceContext, TraitEnvironment, TraitRef}; 14use super::{ExprOrPatId, InferenceContext, TraitRef};
15 15
16impl<'a, D: HirDatabase> InferenceContext<'a, D> { 16impl<'a, D: HirDatabase> InferenceContext<'a, D> {
17 pub(super) fn infer_path( 17 pub(super) fn infer_path(
@@ -39,7 +39,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
39 } 39 }
40 let ty = self.make_ty(type_ref); 40 let ty = self.make_ty(type_ref);
41 let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1); 41 let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1);
42 let ty = Ty::from_type_relative_path(self.db, resolver, ty, remaining_segments_for_ty); 42 let ctx = crate::lower::TyLoweringContext::new(self.db, &resolver);
43 let ty = Ty::from_type_relative_path(&ctx, ty, remaining_segments_for_ty);
43 self.resolve_ty_assoc_item( 44 self.resolve_ty_assoc_item(
44 ty, 45 ty,
45 &path.segments().last().expect("path had at least one segment").name, 46 &path.segments().last().expect("path had at least one segment").name,
@@ -69,12 +70,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
69 ValueNs::EnumVariantId(it) => it.into(), 70 ValueNs::EnumVariantId(it) => it.into(),
70 }; 71 };
71 72
72 let mut ty = self.db.value_ty(typable); 73 let ty = self.db.value_ty(typable);
73 if let Some(self_subst) = self_subst { 74 // self_subst is just for the parent
74 ty = ty.subst(&self_subst); 75 let parent_substs = self_subst.unwrap_or_else(Substs::empty);
75 } 76 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
76 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); 77 let substs = Ty::substs_from_path(&ctx, path, typable);
77 let ty = ty.subst(&substs); 78 let full_substs = Substs::builder(substs.len())
79 .use_parent_substs(&parent_substs)
80 .fill(substs.0[parent_substs.len()..].iter().cloned())
81 .build();
82 let ty = ty.subst(&full_substs);
78 Some(ty) 83 Some(ty)
79 } 84 }
80 85
@@ -98,13 +103,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
98 (TypeNs::TraitId(trait_), true) => { 103 (TypeNs::TraitId(trait_), true) => {
99 let segment = 104 let segment =
100 remaining_segments.last().expect("there should be at least one segment here"); 105 remaining_segments.last().expect("there should be at least one segment here");
101 let trait_ref = TraitRef::from_resolved_path( 106 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
102 self.db, 107 let trait_ref =
103 &self.resolver, 108 TraitRef::from_resolved_path(&ctx, trait_.into(), resolved_segment, None);
104 trait_.into(),
105 resolved_segment,
106 None,
107 );
108 self.resolve_trait_assoc_item(trait_ref, segment, id) 109 self.resolve_trait_assoc_item(trait_ref, segment, id)
109 } 110 }
110 (def, _) => { 111 (def, _) => {
@@ -114,9 +115,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
114 // as Iterator>::Item::default`) 115 // as Iterator>::Item::default`)
115 let remaining_segments_for_ty = 116 let remaining_segments_for_ty =
116 remaining_segments.take(remaining_segments.len() - 1); 117 remaining_segments.take(remaining_segments.len() - 1);
118 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
117 let ty = Ty::from_partly_resolved_hir_path( 119 let ty = Ty::from_partly_resolved_hir_path(
118 self.db, 120 &ctx,
119 &self.resolver,
120 def, 121 def,
121 resolved_segment, 122 resolved_segment,
122 remaining_segments_for_ty, 123 remaining_segments_for_ty,
@@ -173,13 +174,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
173 AssocItemId::ConstId(c) => ValueNs::ConstId(c), 174 AssocItemId::ConstId(c) => ValueNs::ConstId(c),
174 AssocItemId::TypeAliasId(_) => unreachable!(), 175 AssocItemId::TypeAliasId(_) => unreachable!(),
175 }; 176 };
176 let substs = Substs::build_for_def(self.db, item)
177 .use_parent_substs(&trait_ref.substs)
178 .fill_with_params()
179 .build();
180 177
181 self.write_assoc_resolution(id, item); 178 self.write_assoc_resolution(id, item);
182 Some((def, Some(substs))) 179 Some((def, Some(trait_ref.substs)))
183 } 180 }
184 181
185 fn resolve_ty_assoc_item( 182 fn resolve_ty_assoc_item(
@@ -193,14 +190,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
193 } 190 }
194 191
195 let canonical_ty = self.canonicalizer().canonicalize_ty(ty.clone()); 192 let canonical_ty = self.canonicalizer().canonicalize_ty(ty.clone());
196 let env = TraitEnvironment::lower(self.db, &self.resolver);
197 let krate = self.resolver.krate()?; 193 let krate = self.resolver.krate()?;
198 let traits_in_scope = self.resolver.traits_in_scope(self.db); 194 let traits_in_scope = self.resolver.traits_in_scope(self.db);
199 195
200 method_resolution::iterate_method_candidates( 196 method_resolution::iterate_method_candidates(
201 &canonical_ty.value, 197 &canonical_ty.value,
202 self.db, 198 self.db,
203 env, 199 self.trait_env.clone(),
204 krate, 200 krate,
205 &traits_in_scope, 201 &traits_in_scope,
206 Some(name), 202 Some(name),
@@ -219,12 +215,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
219 .fill(iter::repeat_with(|| self.table.new_type_var())) 215 .fill(iter::repeat_with(|| self.table.new_type_var()))
220 .build(); 216 .build();
221 let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs); 217 let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs);
222 let substs = Substs::build_for_def(self.db, item)
223 .use_parent_substs(&impl_substs)
224 .fill_with_params()
225 .build();
226 self.unify(&impl_self_ty, &ty); 218 self.unify(&impl_self_ty, &ty);
227 Some(substs) 219 Some(impl_substs)
228 } 220 }
229 AssocContainerId::TraitId(trait_) => { 221 AssocContainerId::TraitId(trait_) => {
230 // we're picking this method 222 // we're picking this method
@@ -232,15 +224,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
232 .push(ty.clone()) 224 .push(ty.clone())
233 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 225 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
234 .build(); 226 .build();
235 let substs = Substs::build_for_def(self.db, item)
236 .use_parent_substs(&trait_substs)
237 .fill_with_params()
238 .build();
239 self.obligations.push(super::Obligation::Trait(TraitRef { 227 self.obligations.push(super::Obligation::Trait(TraitRef {
240 trait_, 228 trait_,
241 substs: trait_substs, 229 substs: trait_substs.clone(),
242 })); 230 }));
243 Some(substs) 231 Some(trait_substs)
244 } 232 }
245 AssocContainerId::ContainerId(_) => None, 233 AssocContainerId::ContainerId(_) => None,
246 }; 234 };
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index 08d501ccd..c5fe18c85 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -44,8 +44,8 @@ use std::sync::Arc;
44use std::{fmt, iter, mem}; 44use std::{fmt, iter, mem};
45 45
46use hir_def::{ 46use hir_def::{
47 expr::ExprId, type_ref::Mutability, AdtId, AssocContainerId, DefWithBodyId, GenericDefId, 47 expr::ExprId, generics::TypeParamProvenance, type_ref::Mutability, AdtId, AssocContainerId,
48 HasModule, Lookup, TraitId, TypeAliasId, 48 DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, TypeParamId,
49}; 49};
50use hir_expand::name::Name; 50use hir_expand::name::Name;
51use ra_db::{impl_intern_key, salsa, CrateId}; 51use ra_db::{impl_intern_key, salsa, CrateId};
@@ -60,7 +60,9 @@ use display::{HirDisplay, HirFormatter};
60pub use autoderef::autoderef; 60pub use autoderef::autoderef;
61pub use infer::{do_infer_query, InferTy, InferenceResult}; 61pub use infer::{do_infer_query, InferTy, InferenceResult};
62pub use lower::CallableDef; 62pub use lower::CallableDef;
63pub use lower::{callable_item_sig, TyDefId, ValueTyDefId}; 63pub use lower::{
64 callable_item_sig, ImplTraitLoweringMode, TyDefId, TyLoweringContext, ValueTyDefId,
65};
64pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 66pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
65 67
66/// A type constructor or type name: this might be something like the primitive 68/// A type constructor or type name: this might be something like the primitive
@@ -285,22 +287,20 @@ pub enum Ty {
285 /// trait and all its parameters are fully known. 287 /// trait and all its parameters are fully known.
286 Projection(ProjectionTy), 288 Projection(ProjectionTy),
287 289
288 /// A type parameter; for example, `T` in `fn f<T>(x: T) {} 290 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T)
289 Param { 291 /// {}` when we're type-checking the body of that function. In this
290 /// The index of the parameter (starting with parameters from the 292 /// situation, we know this stands for *some* type, but don't know the exact
291 /// surrounding impl, then the current function). 293 /// type.
292 idx: u32, 294 Param(TypeParamId),
293 /// The name of the parameter, for displaying. 295
294 // FIXME get rid of this 296 /// A bound type variable. This is used in various places: when representing
295 name: Name, 297 /// some polymorphic type like the type of function `fn f<T>`, the type
296 }, 298 /// parameters get turned into variables; during trait resolution, inference
297 299 /// variables get turned into bound variables and back; and in `Dyn` the
298 /// A bound type variable. Used during trait resolution to represent Chalk 300 /// `Self` type is represented with a bound variable as well.
299 /// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type.
300 Bound(u32), 301 Bound(u32),
301 302
302 /// A type variable used during type checking. Not to be confused with a 303 /// A type variable used during type checking.
303 /// type parameter.
304 Infer(InferTy), 304 Infer(InferTy),
305 305
306 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). 306 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust).
@@ -364,15 +364,19 @@ impl Substs {
364 } 364 }
365 365
366 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). 366 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
367 pub(crate) fn identity(generic_params: &Generics) -> Substs { 367 pub(crate) fn type_params_for_generics(generic_params: &Generics) -> Substs {
368 Substs( 368 Substs(generic_params.iter().map(|(id, _)| Ty::Param(id)).collect())
369 generic_params.iter().map(|(idx, p)| Ty::Param { idx, name: p.name.clone() }).collect(), 369 }
370 ) 370
371 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
372 pub fn type_params(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> Substs {
373 let params = generics(db, def.into());
374 Substs::type_params_for_generics(&params)
371 } 375 }
372 376
373 /// Return Substs that replace each parameter by a bound variable. 377 /// Return Substs that replace each parameter by a bound variable.
374 pub(crate) fn bound_vars(generic_params: &Generics) -> Substs { 378 pub(crate) fn bound_vars(generic_params: &Generics) -> Substs {
375 Substs(generic_params.iter().map(|(idx, _p)| Ty::Bound(idx)).collect()) 379 Substs(generic_params.iter().enumerate().map(|(idx, _)| Ty::Bound(idx as u32)).collect())
376 } 380 }
377 381
378 pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder { 382 pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder {
@@ -420,11 +424,6 @@ impl SubstsBuilder {
420 self.fill((starting_from..).map(Ty::Bound)) 424 self.fill((starting_from..).map(Ty::Bound))
421 } 425 }
422 426
423 pub fn fill_with_params(self) -> Self {
424 let start = self.vec.len() as u32;
425 self.fill((start..).map(|idx| Ty::Param { idx, name: Name::missing() }))
426 }
427
428 pub fn fill_with_unknown(self) -> Self { 427 pub fn fill_with_unknown(self) -> Self {
429 self.fill(iter::repeat(Ty::Unknown)) 428 self.fill(iter::repeat(Ty::Unknown))
430 } 429 }
@@ -451,6 +450,32 @@ impl Deref for Substs {
451 } 450 }
452} 451}
453 452
453#[derive(Copy, Clone, PartialEq, Eq, Debug)]
454pub struct Binders<T> {
455 pub num_binders: usize,
456 pub value: T,
457}
458
459impl<T> Binders<T> {
460 pub fn new(num_binders: usize, value: T) -> Self {
461 Self { num_binders, value }
462 }
463}
464
465impl<T: TypeWalk> Binders<T> {
466 /// Substitutes all variables.
467 pub fn subst(self, subst: &Substs) -> T {
468 assert_eq!(subst.len(), self.num_binders);
469 self.value.subst_bound_vars(subst)
470 }
471
472 /// Substitutes just a prefix of the variables (shifting the rest).
473 pub fn subst_prefix(self, subst: &Substs) -> Binders<T> {
474 assert!(subst.len() < self.num_binders);
475 Binders::new(self.num_binders - subst.len(), self.value.subst_bound_vars(subst))
476 }
477}
478
454/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. 479/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
455/// Name to be bikeshedded: TraitBound? TraitImplements? 480/// Name to be bikeshedded: TraitBound? TraitImplements?
456#[derive(Clone, PartialEq, Eq, Debug, Hash)] 481#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -551,6 +576,9 @@ pub struct FnSig {
551 params_and_return: Arc<[Ty]>, 576 params_and_return: Arc<[Ty]>,
552} 577}
553 578
579/// A polymorphic function signature.
580pub type PolyFnSig = Binders<FnSig>;
581
554impl FnSig { 582impl FnSig {
555 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig { 583 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig {
556 params.push(ret); 584 params.push(ret);
@@ -730,22 +758,7 @@ pub trait TypeWalk {
730 self 758 self
731 } 759 }
732 760
733 /// Replaces type parameters in this type using the given `Substs`. (So e.g. 761 /// Substitutes `Ty::Bound` vars with the given substitution.
734 /// if `self` is `&[T]`, where type parameter T has index 0, and the
735 /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.)
736 fn subst(self, substs: &Substs) -> Self
737 where
738 Self: Sized,
739 {
740 self.fold(&mut |ty| match ty {
741 Ty::Param { idx, name } => {
742 substs.get(idx as usize).cloned().unwrap_or(Ty::Param { idx, name })
743 }
744 ty => ty,
745 })
746 }
747
748 /// Substitutes `Ty::Bound` vars (as opposed to type parameters).
749 fn subst_bound_vars(mut self, substs: &Substs) -> Self 762 fn subst_bound_vars(mut self, substs: &Substs) -> Self
750 where 763 where
751 Self: Sized, 764 Self: Sized,
@@ -755,6 +768,9 @@ pub trait TypeWalk {
755 &mut Ty::Bound(idx) => { 768 &mut Ty::Bound(idx) => {
756 if idx as usize >= binders && (idx as usize - binders) < substs.len() { 769 if idx as usize >= binders && (idx as usize - binders) < substs.len() {
757 *ty = substs.0[idx as usize - binders].clone(); 770 *ty = substs.0[idx as usize - binders].clone();
771 } else if idx as usize >= binders + substs.len() {
772 // shift free binders
773 *ty = Ty::Bound(idx - substs.len() as u32);
758 } 774 }
759 } 775 }
760 _ => {} 776 _ => {}
@@ -880,7 +896,7 @@ impl HirDisplay for ApplicationTy {
880 write!(f, ") -> {}", sig.ret().display(f.db))?; 896 write!(f, ") -> {}", sig.ret().display(f.db))?;
881 } 897 }
882 TypeCtor::FnDef(def) => { 898 TypeCtor::FnDef(def) => {
883 let sig = f.db.callable_item_signature(def); 899 let sig = f.db.callable_item_signature(def).subst(&self.parameters);
884 let name = match def { 900 let name = match def {
885 CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(), 901 CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(),
886 CallableDef::StructId(s) => f.db.struct_data(s).name.clone(), 902 CallableDef::StructId(s) => f.db.struct_data(s).name.clone(),
@@ -896,9 +912,16 @@ impl HirDisplay for ApplicationTy {
896 } 912 }
897 } 913 }
898 if self.parameters.len() > 0 { 914 if self.parameters.len() > 0 {
899 write!(f, "<")?; 915 let generics = generics(f.db, def.into());
900 f.write_joined(&*self.parameters.0, ", ")?; 916 let (parent_params, self_param, type_params, _impl_trait_params) =
901 write!(f, ">")?; 917 generics.provenance_split();
918 let total_len = parent_params + self_param + type_params;
919 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
920 if total_len > 0 {
921 write!(f, "<")?;
922 f.write_joined(&self.parameters.0[..total_len], ", ")?;
923 write!(f, ">")?;
924 }
902 } 925 }
903 write!(f, "(")?; 926 write!(f, "(")?;
904 f.write_joined(sig.params(), ", ")?; 927 f.write_joined(sig.params(), ", ")?;
@@ -1009,7 +1032,24 @@ impl HirDisplay for Ty {
1009 match self { 1032 match self {
1010 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, 1033 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
1011 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, 1034 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
1012 Ty::Param { name, .. } => write!(f, "{}", name)?, 1035 Ty::Param(id) => {
1036 let generics = generics(f.db, id.parent);
1037 let param_data = &generics.params.types[id.local_id];
1038 match param_data.provenance {
1039 TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => {
1040 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
1041 }
1042 TypeParamProvenance::ArgumentImplTrait => {
1043 write!(f, "impl ")?;
1044 let bounds = f.db.generic_predicates_for_param(*id);
1045 let substs = Substs::type_params_for_generics(&generics);
1046 write_bounds_like_dyn_trait(
1047 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(),
1048 f,
1049 )?;
1050 }
1051 }
1052 }
1013 Ty::Bound(idx) => write!(f, "?{}", idx)?, 1053 Ty::Bound(idx) => write!(f, "?{}", idx)?,
1014 Ty::Dyn(predicates) | Ty::Opaque(predicates) => { 1054 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
1015 match self { 1055 match self {
@@ -1017,66 +1057,7 @@ impl HirDisplay for Ty {
1017 Ty::Opaque(_) => write!(f, "impl ")?, 1057 Ty::Opaque(_) => write!(f, "impl ")?,
1018 _ => unreachable!(), 1058 _ => unreachable!(),
1019 }; 1059 };
1020 // Note: This code is written to produce nice results (i.e. 1060 write_bounds_like_dyn_trait(&predicates, f)?;
1021 // corresponding to surface Rust) for types that can occur in
1022 // actual Rust. It will have weird results if the predicates
1023 // aren't as expected (i.e. self types = $0, projection
1024 // predicates for a certain trait come after the Implemented
1025 // predicate for that trait).
1026 let mut first = true;
1027 let mut angle_open = false;
1028 for p in predicates.iter() {
1029 match p {
1030 GenericPredicate::Implemented(trait_ref) => {
1031 if angle_open {
1032 write!(f, ">")?;
1033 }
1034 if !first {
1035 write!(f, " + ")?;
1036 }
1037 // We assume that the self type is $0 (i.e. the
1038 // existential) here, which is the only thing that's
1039 // possible in actual Rust, and hence don't print it
1040 write!(f, "{}", f.db.trait_data(trait_ref.trait_).name.clone())?;
1041 if trait_ref.substs.len() > 1 {
1042 write!(f, "<")?;
1043 f.write_joined(&trait_ref.substs[1..], ", ")?;
1044 // there might be assoc type bindings, so we leave the angle brackets open
1045 angle_open = true;
1046 }
1047 }
1048 GenericPredicate::Projection(projection_pred) => {
1049 // in types in actual Rust, these will always come
1050 // after the corresponding Implemented predicate
1051 if angle_open {
1052 write!(f, ", ")?;
1053 } else {
1054 write!(f, "<")?;
1055 angle_open = true;
1056 }
1057 let name =
1058 f.db.type_alias_data(projection_pred.projection_ty.associated_ty)
1059 .name
1060 .clone();
1061 write!(f, "{} = ", name)?;
1062 projection_pred.ty.hir_fmt(f)?;
1063 }
1064 GenericPredicate::Error => {
1065 if angle_open {
1066 // impl Trait<X, {error}>
1067 write!(f, ", ")?;
1068 } else if !first {
1069 // impl Trait + {error}
1070 write!(f, " + ")?;
1071 }
1072 p.hir_fmt(f)?;
1073 }
1074 }
1075 first = false;
1076 }
1077 if angle_open {
1078 write!(f, ">")?;
1079 }
1080 } 1061 }
1081 Ty::Unknown => write!(f, "{{unknown}}")?, 1062 Ty::Unknown => write!(f, "{{unknown}}")?,
1082 Ty::Infer(..) => write!(f, "_")?, 1063 Ty::Infer(..) => write!(f, "_")?,
@@ -1085,6 +1066,71 @@ impl HirDisplay for Ty {
1085 } 1066 }
1086} 1067}
1087 1068
1069fn write_bounds_like_dyn_trait(
1070 predicates: &[GenericPredicate],
1071 f: &mut HirFormatter<impl HirDatabase>,
1072) -> fmt::Result {
1073 // Note: This code is written to produce nice results (i.e.
1074 // corresponding to surface Rust) for types that can occur in
1075 // actual Rust. It will have weird results if the predicates
1076 // aren't as expected (i.e. self types = $0, projection
1077 // predicates for a certain trait come after the Implemented
1078 // predicate for that trait).
1079 let mut first = true;
1080 let mut angle_open = false;
1081 for p in predicates.iter() {
1082 match p {
1083 GenericPredicate::Implemented(trait_ref) => {
1084 if angle_open {
1085 write!(f, ">")?;
1086 }
1087 if !first {
1088 write!(f, " + ")?;
1089 }
1090 // We assume that the self type is $0 (i.e. the
1091 // existential) here, which is the only thing that's
1092 // possible in actual Rust, and hence don't print it
1093 write!(f, "{}", f.db.trait_data(trait_ref.trait_).name.clone())?;
1094 if trait_ref.substs.len() > 1 {
1095 write!(f, "<")?;
1096 f.write_joined(&trait_ref.substs[1..], ", ")?;
1097 // there might be assoc type bindings, so we leave the angle brackets open
1098 angle_open = true;
1099 }
1100 }
1101 GenericPredicate::Projection(projection_pred) => {
1102 // in types in actual Rust, these will always come
1103 // after the corresponding Implemented predicate
1104 if angle_open {
1105 write!(f, ", ")?;
1106 } else {
1107 write!(f, "<")?;
1108 angle_open = true;
1109 }
1110 let name =
1111 f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name.clone();
1112 write!(f, "{} = ", name)?;
1113 projection_pred.ty.hir_fmt(f)?;
1114 }
1115 GenericPredicate::Error => {
1116 if angle_open {
1117 // impl Trait<X, {error}>
1118 write!(f, ", ")?;
1119 } else if !first {
1120 // impl Trait + {error}
1121 write!(f, " + ")?;
1122 }
1123 p.hir_fmt(f)?;
1124 }
1125 }
1126 first = false;
1127 }
1128 if angle_open {
1129 write!(f, ">")?;
1130 }
1131 Ok(())
1132}
1133
1088impl TraitRef { 1134impl TraitRef {
1089 fn hir_fmt_ext(&self, f: &mut HirFormatter<impl HirDatabase>, use_as: bool) -> fmt::Result { 1135 fn hir_fmt_ext(&self, f: &mut HirFormatter<impl HirDatabase>, use_as: bool) -> fmt::Result {
1090 if f.should_truncate() { 1136 if f.should_truncate() {
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index 2c2ecee9c..c68c5852b 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -10,12 +10,13 @@ use std::sync::Arc;
10 10
11use hir_def::{ 11use hir_def::{
12 builtin_type::BuiltinType, 12 builtin_type::BuiltinType,
13 generics::WherePredicate, 13 generics::{TypeParamProvenance, WherePredicate, WherePredicateTarget},
14 path::{GenericArg, Path, PathSegment, PathSegments}, 14 path::{GenericArg, Path, PathSegment, PathSegments},
15 resolver::{HasResolver, Resolver, TypeNs}, 15 resolver::{HasResolver, Resolver, TypeNs},
16 type_ref::{TypeBound, TypeRef}, 16 type_ref::{TypeBound, TypeRef},
17 AdtId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, 17 AdtId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId,
18 LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId, 18 LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
19 VariantId,
19}; 20};
20use ra_arena::map::ArenaMap; 21use ra_arena::map::ArenaMap;
21use ra_db::CrateId; 22use ra_db::CrateId;
@@ -27,63 +28,158 @@ use crate::{
27 all_super_traits, associated_type_by_name_including_super_traits, generics, make_mut_slice, 28 all_super_traits, associated_type_by_name_including_super_traits, generics, make_mut_slice,
28 variant_data, 29 variant_data,
29 }, 30 },
30 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, 31 Binders, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, ProjectionTy, Substs,
31 Ty, TypeCtor, TypeWalk, 32 TraitEnvironment, TraitRef, Ty, TypeCtor,
32}; 33};
33 34
35#[derive(Debug)]
36pub struct TyLoweringContext<'a, DB: HirDatabase> {
37 pub db: &'a DB,
38 pub resolver: &'a Resolver,
39 /// Note: Conceptually, it's thinkable that we could be in a location where
40 /// some type params should be represented as placeholders, and others
41 /// should be converted to variables. I think in practice, this isn't
42 /// possible currently, so this should be fine for now.
43 pub type_param_mode: TypeParamLoweringMode,
44 pub impl_trait_mode: ImplTraitLoweringMode,
45 pub impl_trait_counter: std::cell::Cell<u16>,
46}
47
48impl<'a, DB: HirDatabase> TyLoweringContext<'a, DB> {
49 pub fn new(db: &'a DB, resolver: &'a Resolver) -> Self {
50 let impl_trait_counter = std::cell::Cell::new(0);
51 let impl_trait_mode = ImplTraitLoweringMode::Disallowed;
52 let type_param_mode = TypeParamLoweringMode::Placeholder;
53 Self { db, resolver, impl_trait_mode, impl_trait_counter, type_param_mode }
54 }
55
56 pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
57 Self { impl_trait_mode, ..self }
58 }
59
60 pub fn with_type_param_mode(self, type_param_mode: TypeParamLoweringMode) -> Self {
61 Self { type_param_mode, ..self }
62 }
63}
64
65#[derive(Copy, Clone, Debug, PartialEq, Eq)]
66pub enum ImplTraitLoweringMode {
67 /// `impl Trait` gets lowered into an opaque type that doesn't unify with
68 /// anything except itself. This is used in places where values flow 'out',
69 /// i.e. for arguments of the function we're currently checking, and return
70 /// types of functions we're calling.
71 Opaque,
72 /// `impl Trait` gets lowered into a type variable. Used for argument
73 /// position impl Trait when inside the respective function, since it allows
74 /// us to support that without Chalk.
75 Param,
76 /// `impl Trait` gets lowered into a variable that can unify with some
77 /// type. This is used in places where values flow 'in', i.e. for arguments
78 /// of functions we're calling, and the return type of the function we're
79 /// currently checking.
80 Variable,
81 /// `impl Trait` is disallowed and will be an error.
82 Disallowed,
83}
84
85#[derive(Copy, Clone, Debug, PartialEq, Eq)]
86pub enum TypeParamLoweringMode {
87 Placeholder,
88 Variable,
89}
90
34impl Ty { 91impl Ty {
35 pub fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { 92 pub fn from_hir(ctx: &TyLoweringContext<'_, impl HirDatabase>, type_ref: &TypeRef) -> Self {
36 match type_ref { 93 match type_ref {
37 TypeRef::Never => Ty::simple(TypeCtor::Never), 94 TypeRef::Never => Ty::simple(TypeCtor::Never),
38 TypeRef::Tuple(inner) => { 95 TypeRef::Tuple(inner) => {
39 let inner_tys: Arc<[Ty]> = 96 let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect();
40 inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect();
41 Ty::apply( 97 Ty::apply(
42 TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, 98 TypeCtor::Tuple { cardinality: inner_tys.len() as u16 },
43 Substs(inner_tys), 99 Substs(inner_tys),
44 ) 100 )
45 } 101 }
46 TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path), 102 TypeRef::Path(path) => Ty::from_hir_path(ctx, path),
47 TypeRef::RawPtr(inner, mutability) => { 103 TypeRef::RawPtr(inner, mutability) => {
48 let inner_ty = Ty::from_hir(db, resolver, inner); 104 let inner_ty = Ty::from_hir(ctx, inner);
49 Ty::apply_one(TypeCtor::RawPtr(*mutability), inner_ty) 105 Ty::apply_one(TypeCtor::RawPtr(*mutability), inner_ty)
50 } 106 }
51 TypeRef::Array(inner) => { 107 TypeRef::Array(inner) => {
52 let inner_ty = Ty::from_hir(db, resolver, inner); 108 let inner_ty = Ty::from_hir(ctx, inner);
53 Ty::apply_one(TypeCtor::Array, inner_ty) 109 Ty::apply_one(TypeCtor::Array, inner_ty)
54 } 110 }
55 TypeRef::Slice(inner) => { 111 TypeRef::Slice(inner) => {
56 let inner_ty = Ty::from_hir(db, resolver, inner); 112 let inner_ty = Ty::from_hir(ctx, inner);
57 Ty::apply_one(TypeCtor::Slice, inner_ty) 113 Ty::apply_one(TypeCtor::Slice, inner_ty)
58 } 114 }
59 TypeRef::Reference(inner, mutability) => { 115 TypeRef::Reference(inner, mutability) => {
60 let inner_ty = Ty::from_hir(db, resolver, inner); 116 let inner_ty = Ty::from_hir(ctx, inner);
61 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) 117 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty)
62 } 118 }
63 TypeRef::Placeholder => Ty::Unknown, 119 TypeRef::Placeholder => Ty::Unknown,
64 TypeRef::Fn(params) => { 120 TypeRef::Fn(params) => {
65 let sig = Substs(params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect()); 121 let sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect());
66 Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig) 122 Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig)
67 } 123 }
68 TypeRef::DynTrait(bounds) => { 124 TypeRef::DynTrait(bounds) => {
69 let self_ty = Ty::Bound(0); 125 let self_ty = Ty::Bound(0);
70 let predicates = bounds 126 let predicates = bounds
71 .iter() 127 .iter()
72 .flat_map(|b| { 128 .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone()))
73 GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone())
74 })
75 .collect(); 129 .collect();
76 Ty::Dyn(predicates) 130 Ty::Dyn(predicates)
77 } 131 }
78 TypeRef::ImplTrait(bounds) => { 132 TypeRef::ImplTrait(bounds) => {
79 let self_ty = Ty::Bound(0); 133 match ctx.impl_trait_mode {
80 let predicates = bounds 134 ImplTraitLoweringMode::Opaque => {
81 .iter() 135 let self_ty = Ty::Bound(0);
82 .flat_map(|b| { 136 let predicates = bounds
83 GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone()) 137 .iter()
84 }) 138 .flat_map(|b| {
85 .collect(); 139 GenericPredicate::from_type_bound(ctx, b, self_ty.clone())
86 Ty::Opaque(predicates) 140 })
141 .collect();
142 Ty::Opaque(predicates)
143 }
144 ImplTraitLoweringMode::Param => {
145 let idx = ctx.impl_trait_counter.get();
146 ctx.impl_trait_counter.set(idx + 1);
147 if let Some(def) = ctx.resolver.generic_def() {
148 let generics = generics(ctx.db, def);
149 let param = generics
150 .iter()
151 .filter(|(_, data)| {
152 data.provenance == TypeParamProvenance::ArgumentImplTrait
153 })
154 .nth(idx as usize)
155 .map_or(Ty::Unknown, |(id, _)| Ty::Param(id));
156 param
157 } else {
158 Ty::Unknown
159 }
160 }
161 ImplTraitLoweringMode::Variable => {
162 let idx = ctx.impl_trait_counter.get();
163 ctx.impl_trait_counter.set(idx + 1);
164 let (parent_params, self_params, list_params, _impl_trait_params) =
165 if let Some(def) = ctx.resolver.generic_def() {
166 let generics = generics(ctx.db, def);
167 generics.provenance_split()
168 } else {
169 (0, 0, 0, 0)
170 };
171 Ty::Bound(
172 idx as u32
173 + parent_params as u32
174 + self_params as u32
175 + list_params as u32,
176 )
177 }
178 ImplTraitLoweringMode::Disallowed => {
179 // FIXME: report error
180 Ty::Unknown
181 }
182 }
87 } 183 }
88 TypeRef::Error => Ty::Unknown, 184 TypeRef::Error => Ty::Unknown,
89 } 185 }
@@ -93,10 +189,9 @@ impl Ty {
93 /// lower the self types of the predicates since that could lead to cycles. 189 /// lower the self types of the predicates since that could lead to cycles.
94 /// So we just check here if the `type_ref` resolves to a generic param, and which. 190 /// So we just check here if the `type_ref` resolves to a generic param, and which.
95 fn from_hir_only_param( 191 fn from_hir_only_param(
96 db: &impl HirDatabase, 192 ctx: &TyLoweringContext<'_, impl HirDatabase>,
97 resolver: &Resolver,
98 type_ref: &TypeRef, 193 type_ref: &TypeRef,
99 ) -> Option<u32> { 194 ) -> Option<TypeParamId> {
100 let path = match type_ref { 195 let path = match type_ref {
101 TypeRef::Path(path) => path, 196 TypeRef::Path(path) => path,
102 _ => return None, 197 _ => return None,
@@ -107,29 +202,26 @@ impl Ty {
107 if path.segments().len() > 1 { 202 if path.segments().len() > 1 {
108 return None; 203 return None;
109 } 204 }
110 let resolution = match resolver.resolve_path_in_type_ns(db, path.mod_path()) { 205 let resolution = match ctx.resolver.resolve_path_in_type_ns(ctx.db, path.mod_path()) {
111 Some((it, None)) => it, 206 Some((it, None)) => it,
112 _ => return None, 207 _ => return None,
113 }; 208 };
114 if let TypeNs::GenericParam(param_id) = resolution { 209 if let TypeNs::GenericParam(param_id) = resolution {
115 let generics = generics(db, resolver.generic_def().expect("generics in scope")); 210 Some(param_id)
116 let idx = generics.param_idx(param_id);
117 Some(idx)
118 } else { 211 } else {
119 None 212 None
120 } 213 }
121 } 214 }
122 215
123 pub(crate) fn from_type_relative_path( 216 pub(crate) fn from_type_relative_path(
124 db: &impl HirDatabase, 217 ctx: &TyLoweringContext<'_, impl HirDatabase>,
125 resolver: &Resolver,
126 ty: Ty, 218 ty: Ty,
127 remaining_segments: PathSegments<'_>, 219 remaining_segments: PathSegments<'_>,
128 ) -> Ty { 220 ) -> Ty {
129 if remaining_segments.len() == 1 { 221 if remaining_segments.len() == 1 {
130 // resolve unselected assoc types 222 // resolve unselected assoc types
131 let segment = remaining_segments.first().unwrap(); 223 let segment = remaining_segments.first().unwrap();
132 Ty::select_associated_type(db, resolver, ty, segment) 224 Ty::select_associated_type(ctx, ty, segment)
133 } else if remaining_segments.len() > 1 { 225 } else if remaining_segments.len() > 1 {
134 // FIXME report error (ambiguous associated type) 226 // FIXME report error (ambiguous associated type)
135 Ty::Unknown 227 Ty::Unknown
@@ -139,20 +231,18 @@ impl Ty {
139 } 231 }
140 232
141 pub(crate) fn from_partly_resolved_hir_path( 233 pub(crate) fn from_partly_resolved_hir_path(
142 db: &impl HirDatabase, 234 ctx: &TyLoweringContext<'_, impl HirDatabase>,
143 resolver: &Resolver,
144 resolution: TypeNs, 235 resolution: TypeNs,
145 resolved_segment: PathSegment<'_>, 236 resolved_segment: PathSegment<'_>,
146 remaining_segments: PathSegments<'_>, 237 remaining_segments: PathSegments<'_>,
147 ) -> Ty { 238 ) -> Ty {
148 let ty = match resolution { 239 let ty = match resolution {
149 TypeNs::TraitId(trait_) => { 240 TypeNs::TraitId(trait_) => {
150 let trait_ref = 241 let trait_ref = TraitRef::from_resolved_path(ctx, trait_, resolved_segment, None);
151 TraitRef::from_resolved_path(db, resolver, trait_, resolved_segment, None);
152 return if remaining_segments.len() == 1 { 242 return if remaining_segments.len() == 1 {
153 let segment = remaining_segments.first().unwrap(); 243 let segment = remaining_segments.first().unwrap();
154 let associated_ty = associated_type_by_name_including_super_traits( 244 let associated_ty = associated_type_by_name_including_super_traits(
155 db, 245 ctx.db,
156 trait_ref.trait_, 246 trait_ref.trait_,
157 &segment.name, 247 &segment.name,
158 ); 248 );
@@ -177,37 +267,55 @@ impl Ty {
177 }; 267 };
178 } 268 }
179 TypeNs::GenericParam(param_id) => { 269 TypeNs::GenericParam(param_id) => {
180 let generics = generics(db, resolver.generic_def().expect("generics in scope")); 270 let generics =
181 let idx = generics.param_idx(param_id); 271 generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope"));
182 // FIXME: maybe return name in resolution? 272 match ctx.type_param_mode {
183 let name = generics.param_name(param_id); 273 TypeParamLoweringMode::Placeholder => Ty::Param(param_id),
184 Ty::Param { idx, name } 274 TypeParamLoweringMode::Variable => {
275 let idx = generics.param_idx(param_id).expect("matching generics");
276 Ty::Bound(idx)
277 }
278 }
185 } 279 }
186 TypeNs::SelfType(impl_id) => db.impl_self_ty(impl_id).clone(), 280 TypeNs::SelfType(impl_id) => {
187 TypeNs::AdtSelfType(adt) => db.ty(adt.into()), 281 let generics = generics(ctx.db, impl_id.into());
188 282 let substs = match ctx.type_param_mode {
189 TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), 283 TypeParamLoweringMode::Placeholder => {
190 TypeNs::BuiltinType(it) => { 284 Substs::type_params_for_generics(&generics)
191 Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) 285 }
286 TypeParamLoweringMode::Variable => Substs::bound_vars(&generics),
287 };
288 ctx.db.impl_self_ty(impl_id).subst(&substs)
192 } 289 }
193 TypeNs::TypeAliasId(it) => { 290 TypeNs::AdtSelfType(adt) => {
194 Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) 291 let generics = generics(ctx.db, adt.into());
292 let substs = match ctx.type_param_mode {
293 TypeParamLoweringMode::Placeholder => {
294 Substs::type_params_for_generics(&generics)
295 }
296 TypeParamLoweringMode::Variable => Substs::bound_vars(&generics),
297 };
298 ctx.db.ty(adt.into()).subst(&substs)
195 } 299 }
300
301 TypeNs::AdtId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()),
302 TypeNs::BuiltinType(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()),
303 TypeNs::TypeAliasId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()),
196 // FIXME: report error 304 // FIXME: report error
197 TypeNs::EnumVariantId(_) => return Ty::Unknown, 305 TypeNs::EnumVariantId(_) => return Ty::Unknown,
198 }; 306 };
199 307
200 Ty::from_type_relative_path(db, resolver, ty, remaining_segments) 308 Ty::from_type_relative_path(ctx, ty, remaining_segments)
201 } 309 }
202 310
203 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Ty { 311 pub(crate) fn from_hir_path(ctx: &TyLoweringContext<'_, impl HirDatabase>, path: &Path) -> Ty {
204 // Resolve the path (in type namespace) 312 // Resolve the path (in type namespace)
205 if let Some(type_ref) = path.type_anchor() { 313 if let Some(type_ref) = path.type_anchor() {
206 let ty = Ty::from_hir(db, resolver, &type_ref); 314 let ty = Ty::from_hir(ctx, &type_ref);
207 return Ty::from_type_relative_path(db, resolver, ty, path.segments()); 315 return Ty::from_type_relative_path(ctx, ty, path.segments());
208 } 316 }
209 let (resolution, remaining_index) = 317 let (resolution, remaining_index) =
210 match resolver.resolve_path_in_type_ns(db, path.mod_path()) { 318 match ctx.resolver.resolve_path_in_type_ns(ctx.db, path.mod_path()) {
211 Some(it) => it, 319 Some(it) => it,
212 None => return Ty::Unknown, 320 None => return Ty::Unknown,
213 }; 321 };
@@ -218,39 +326,44 @@ impl Ty {
218 ), 326 ),
219 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)), 327 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)),
220 }; 328 };
221 Ty::from_partly_resolved_hir_path( 329 Ty::from_partly_resolved_hir_path(ctx, resolution, resolved_segment, remaining_segments)
222 db,
223 resolver,
224 resolution,
225 resolved_segment,
226 remaining_segments,
227 )
228 } 330 }
229 331
230 fn select_associated_type( 332 fn select_associated_type(
231 db: &impl HirDatabase, 333 ctx: &TyLoweringContext<'_, impl HirDatabase>,
232 resolver: &Resolver,
233 self_ty: Ty, 334 self_ty: Ty,
234 segment: PathSegment<'_>, 335 segment: PathSegment<'_>,
235 ) -> Ty { 336 ) -> Ty {
236 let param_idx = match self_ty { 337 let def = match ctx.resolver.generic_def() {
237 Ty::Param { idx, .. } => idx,
238 _ => return Ty::Unknown, // Error: Ambiguous associated type
239 };
240 let def = match resolver.generic_def() {
241 Some(def) => def, 338 Some(def) => def,
242 None => return Ty::Unknown, // this can't actually happen 339 None => return Ty::Unknown, // this can't actually happen
243 }; 340 };
244 let predicates = db.generic_predicates_for_param(def.into(), param_idx); 341 let param_id = match self_ty {
245 let traits_from_env = predicates.iter().filter_map(|pred| match pred { 342 Ty::Param(id) if ctx.type_param_mode == TypeParamLoweringMode::Placeholder => id,
246 GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), 343 Ty::Bound(idx) if ctx.type_param_mode == TypeParamLoweringMode::Variable => {
344 let generics = generics(ctx.db, def);
345 let param_id = if let Some((id, _)) = generics.iter().nth(idx as usize) {
346 id
347 } else {
348 return Ty::Unknown;
349 };
350 param_id
351 }
352 _ => return Ty::Unknown, // Error: Ambiguous associated type
353 };
354 let predicates = ctx.db.generic_predicates_for_param(param_id);
355 let traits_from_env = predicates.iter().filter_map(|pred| match &pred.value {
356 GenericPredicate::Implemented(tr) => Some(tr.trait_),
247 _ => None, 357 _ => None,
248 }); 358 });
249 let traits = traits_from_env.flat_map(|t| all_super_traits(db, t)); 359 let traits = traits_from_env.flat_map(|t| all_super_traits(ctx.db, t));
250 for t in traits { 360 for t in traits {
251 if let Some(associated_ty) = db.trait_data(t).associated_type_by_name(&segment.name) { 361 if let Some(associated_ty) = ctx.db.trait_data(t).associated_type_by_name(&segment.name)
252 let substs = 362 {
253 Substs::build_for_def(db, t).push(self_ty.clone()).fill_with_unknown().build(); 363 let substs = Substs::build_for_def(ctx.db, t)
364 .push(self_ty.clone())
365 .fill_with_unknown()
366 .build();
254 // FIXME handle type parameters on the segment 367 // FIXME handle type parameters on the segment
255 return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); 368 return Ty::Projection(ProjectionTy { associated_ty, parameters: substs });
256 } 369 }
@@ -259,8 +372,7 @@ impl Ty {
259 } 372 }
260 373
261 fn from_hir_path_inner( 374 fn from_hir_path_inner(
262 db: &impl HirDatabase, 375 ctx: &TyLoweringContext<'_, impl HirDatabase>,
263 resolver: &Resolver,
264 segment: PathSegment<'_>, 376 segment: PathSegment<'_>,
265 typable: TyDefId, 377 typable: TyDefId,
266 ) -> Ty { 378 ) -> Ty {
@@ -269,15 +381,14 @@ impl Ty {
269 TyDefId::AdtId(it) => Some(it.into()), 381 TyDefId::AdtId(it) => Some(it.into()),
270 TyDefId::TypeAliasId(it) => Some(it.into()), 382 TyDefId::TypeAliasId(it) => Some(it.into()),
271 }; 383 };
272 let substs = substs_from_path_segment(db, resolver, segment, generic_def, false); 384 let substs = substs_from_path_segment(ctx, segment, generic_def, false);
273 db.ty(typable).subst(&substs) 385 ctx.db.ty(typable).subst(&substs)
274 } 386 }
275 387
276 /// Collect generic arguments from a path into a `Substs`. See also 388 /// Collect generic arguments from a path into a `Substs`. See also
277 /// `create_substs_for_ast_path` and `def_to_ty` in rustc. 389 /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
278 pub(super) fn substs_from_path( 390 pub(super) fn substs_from_path(
279 db: &impl HirDatabase, 391 ctx: &TyLoweringContext<'_, impl HirDatabase>,
280 resolver: &Resolver,
281 path: &Path, 392 path: &Path,
282 // Note that we don't call `db.value_type(resolved)` here, 393 // Note that we don't call `db.value_type(resolved)` here,
283 // `ValueTyDefId` is just a convenient way to pass generics and 394 // `ValueTyDefId` is just a convenient way to pass generics and
@@ -305,52 +416,49 @@ impl Ty {
305 (segment, Some(var.parent.into())) 416 (segment, Some(var.parent.into()))
306 } 417 }
307 }; 418 };
308 substs_from_path_segment(db, resolver, segment, generic_def, false) 419 substs_from_path_segment(ctx, segment, generic_def, false)
309 } 420 }
310} 421}
311 422
312pub(super) fn substs_from_path_segment( 423pub(super) fn substs_from_path_segment(
313 db: &impl HirDatabase, 424 ctx: &TyLoweringContext<'_, impl HirDatabase>,
314 resolver: &Resolver,
315 segment: PathSegment<'_>, 425 segment: PathSegment<'_>,
316 def_generic: Option<GenericDefId>, 426 def_generic: Option<GenericDefId>,
317 add_self_param: bool, 427 _add_self_param: bool,
318) -> Substs { 428) -> Substs {
319 let mut substs = Vec::new(); 429 let mut substs = Vec::new();
320 let def_generics = def_generic.map(|def| generics(db, def.into())); 430 let def_generics = def_generic.map(|def| generics(ctx.db, def.into()));
321 431
322 let (total_len, parent_len, child_len) = def_generics.map_or((0, 0, 0), |g| g.len_split()); 432 let (parent_params, self_params, type_params, impl_trait_params) =
323 substs.extend(iter::repeat(Ty::Unknown).take(parent_len)); 433 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split());
324 if add_self_param { 434 substs.extend(iter::repeat(Ty::Unknown).take(parent_params));
325 // FIXME this add_self_param argument is kind of a hack: Traits have the
326 // Self type as an implicit first type parameter, but it can't be
327 // actually provided in the type arguments
328 // (well, actually sometimes it can, in the form of type-relative paths: `<Foo as Default>::default()`)
329 substs.push(Ty::Unknown);
330 }
331 if let Some(generic_args) = &segment.args_and_bindings { 435 if let Some(generic_args) = &segment.args_and_bindings {
436 if !generic_args.has_self_type {
437 substs.extend(iter::repeat(Ty::Unknown).take(self_params));
438 }
439 let expected_num =
440 if generic_args.has_self_type { self_params + type_params } else { type_params };
441 let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
332 // if args are provided, it should be all of them, but we can't rely on that 442 // if args are provided, it should be all of them, but we can't rely on that
333 let self_param_correction = if add_self_param { 1 } else { 0 }; 443 for arg in generic_args.args.iter().skip(skip).take(expected_num) {
334 let child_len = child_len - self_param_correction;
335 for arg in generic_args.args.iter().take(child_len) {
336 match arg { 444 match arg {
337 GenericArg::Type(type_ref) => { 445 GenericArg::Type(type_ref) => {
338 let ty = Ty::from_hir(db, resolver, type_ref); 446 let ty = Ty::from_hir(ctx, type_ref);
339 substs.push(ty); 447 substs.push(ty);
340 } 448 }
341 } 449 }
342 } 450 }
343 } 451 }
452 let total_len = parent_params + self_params + type_params + impl_trait_params;
344 // add placeholders for args that were not provided 453 // add placeholders for args that were not provided
345 let supplied_params = substs.len(); 454 for _ in substs.len()..total_len {
346 for _ in supplied_params..total_len {
347 substs.push(Ty::Unknown); 455 substs.push(Ty::Unknown);
348 } 456 }
349 assert_eq!(substs.len(), total_len); 457 assert_eq!(substs.len(), total_len);
350 458
351 // handle defaults 459 // handle defaults
352 if let Some(def_generic) = def_generic { 460 if let Some(def_generic) = def_generic {
353 let default_substs = db.generic_defaults(def_generic.into()); 461 let default_substs = ctx.db.generic_defaults(def_generic.into());
354 assert_eq!(substs.len(), default_substs.len()); 462 assert_eq!(substs.len(), default_substs.len());
355 463
356 for (i, default_ty) in default_substs.iter().enumerate() { 464 for (i, default_ty) in default_substs.iter().enumerate() {
@@ -365,27 +473,25 @@ pub(super) fn substs_from_path_segment(
365 473
366impl TraitRef { 474impl TraitRef {
367 fn from_path( 475 fn from_path(
368 db: &impl HirDatabase, 476 ctx: &TyLoweringContext<'_, impl HirDatabase>,
369 resolver: &Resolver,
370 path: &Path, 477 path: &Path,
371 explicit_self_ty: Option<Ty>, 478 explicit_self_ty: Option<Ty>,
372 ) -> Option<Self> { 479 ) -> Option<Self> {
373 let resolved = match resolver.resolve_path_in_type_ns_fully(db, path.mod_path())? { 480 let resolved = match ctx.resolver.resolve_path_in_type_ns_fully(ctx.db, path.mod_path())? {
374 TypeNs::TraitId(tr) => tr, 481 TypeNs::TraitId(tr) => tr,
375 _ => return None, 482 _ => return None,
376 }; 483 };
377 let segment = path.segments().last().expect("path should have at least one segment"); 484 let segment = path.segments().last().expect("path should have at least one segment");
378 Some(TraitRef::from_resolved_path(db, resolver, resolved.into(), segment, explicit_self_ty)) 485 Some(TraitRef::from_resolved_path(ctx, resolved.into(), segment, explicit_self_ty))
379 } 486 }
380 487
381 pub(crate) fn from_resolved_path( 488 pub(crate) fn from_resolved_path(
382 db: &impl HirDatabase, 489 ctx: &TyLoweringContext<'_, impl HirDatabase>,
383 resolver: &Resolver,
384 resolved: TraitId, 490 resolved: TraitId,
385 segment: PathSegment<'_>, 491 segment: PathSegment<'_>,
386 explicit_self_ty: Option<Ty>, 492 explicit_self_ty: Option<Ty>,
387 ) -> Self { 493 ) -> Self {
388 let mut substs = TraitRef::substs_from_path(db, resolver, segment, resolved); 494 let mut substs = TraitRef::substs_from_path(ctx, segment, resolved);
389 if let Some(self_ty) = explicit_self_ty { 495 if let Some(self_ty) = explicit_self_ty {
390 make_mut_slice(&mut substs.0)[0] = self_ty; 496 make_mut_slice(&mut substs.0)[0] = self_ty;
391 } 497 }
@@ -393,8 +499,7 @@ impl TraitRef {
393 } 499 }
394 500
395 fn from_hir( 501 fn from_hir(
396 db: &impl HirDatabase, 502 ctx: &TyLoweringContext<'_, impl HirDatabase>,
397 resolver: &Resolver,
398 type_ref: &TypeRef, 503 type_ref: &TypeRef,
399 explicit_self_ty: Option<Ty>, 504 explicit_self_ty: Option<Ty>,
400 ) -> Option<Self> { 505 ) -> Option<Self> {
@@ -402,28 +507,26 @@ impl TraitRef {
402 TypeRef::Path(path) => path, 507 TypeRef::Path(path) => path,
403 _ => return None, 508 _ => return None,
404 }; 509 };
405 TraitRef::from_path(db, resolver, path, explicit_self_ty) 510 TraitRef::from_path(ctx, path, explicit_self_ty)
406 } 511 }
407 512
408 fn substs_from_path( 513 fn substs_from_path(
409 db: &impl HirDatabase, 514 ctx: &TyLoweringContext<'_, impl HirDatabase>,
410 resolver: &Resolver,
411 segment: PathSegment<'_>, 515 segment: PathSegment<'_>,
412 resolved: TraitId, 516 resolved: TraitId,
413 ) -> Substs { 517 ) -> Substs {
414 let has_self_param = 518 let has_self_param =
415 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false); 519 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false);
416 substs_from_path_segment(db, resolver, segment, Some(resolved.into()), !has_self_param) 520 substs_from_path_segment(ctx, segment, Some(resolved.into()), !has_self_param)
417 } 521 }
418 522
419 pub(crate) fn from_type_bound( 523 pub(crate) fn from_type_bound(
420 db: &impl HirDatabase, 524 ctx: &TyLoweringContext<'_, impl HirDatabase>,
421 resolver: &Resolver,
422 bound: &TypeBound, 525 bound: &TypeBound,
423 self_ty: Ty, 526 self_ty: Ty,
424 ) -> Option<TraitRef> { 527 ) -> Option<TraitRef> {
425 match bound { 528 match bound {
426 TypeBound::Path(path) => TraitRef::from_path(db, resolver, path, Some(self_ty)), 529 TypeBound::Path(path) => TraitRef::from_path(ctx, path, Some(self_ty)),
427 TypeBound::Error => None, 530 TypeBound::Error => None,
428 } 531 }
429 } 532 }
@@ -431,33 +534,44 @@ impl TraitRef {
431 534
432impl GenericPredicate { 535impl GenericPredicate {
433 pub(crate) fn from_where_predicate<'a>( 536 pub(crate) fn from_where_predicate<'a>(
434 db: &'a impl HirDatabase, 537 ctx: &'a TyLoweringContext<'a, impl HirDatabase>,
435 resolver: &'a Resolver,
436 where_predicate: &'a WherePredicate, 538 where_predicate: &'a WherePredicate,
437 ) -> impl Iterator<Item = GenericPredicate> + 'a { 539 ) -> impl Iterator<Item = GenericPredicate> + 'a {
438 let self_ty = Ty::from_hir(db, resolver, &where_predicate.type_ref); 540 let self_ty = match &where_predicate.target {
439 GenericPredicate::from_type_bound(db, resolver, &where_predicate.bound, self_ty) 541 WherePredicateTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref),
542 WherePredicateTarget::TypeParam(param_id) => {
543 let generic_def = ctx.resolver.generic_def().expect("generics in scope");
544 let generics = generics(ctx.db, generic_def);
545 let param_id = hir_def::TypeParamId { parent: generic_def, local_id: *param_id };
546 match ctx.type_param_mode {
547 TypeParamLoweringMode::Placeholder => Ty::Param(param_id),
548 TypeParamLoweringMode::Variable => {
549 let idx = generics.param_idx(param_id).expect("matching generics");
550 Ty::Bound(idx)
551 }
552 }
553 }
554 };
555 GenericPredicate::from_type_bound(ctx, &where_predicate.bound, self_ty)
440 } 556 }
441 557
442 pub(crate) fn from_type_bound<'a>( 558 pub(crate) fn from_type_bound<'a>(
443 db: &'a impl HirDatabase, 559 ctx: &'a TyLoweringContext<'a, impl HirDatabase>,
444 resolver: &'a Resolver,
445 bound: &'a TypeBound, 560 bound: &'a TypeBound,
446 self_ty: Ty, 561 self_ty: Ty,
447 ) -> impl Iterator<Item = GenericPredicate> + 'a { 562 ) -> impl Iterator<Item = GenericPredicate> + 'a {
448 let trait_ref = TraitRef::from_type_bound(db, &resolver, bound, self_ty); 563 let trait_ref = TraitRef::from_type_bound(ctx, bound, self_ty);
449 iter::once(trait_ref.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented)) 564 iter::once(trait_ref.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented))
450 .chain( 565 .chain(
451 trait_ref.into_iter().flat_map(move |tr| { 566 trait_ref
452 assoc_type_bindings_from_type_bound(db, resolver, bound, tr) 567 .into_iter()
453 }), 568 .flat_map(move |tr| assoc_type_bindings_from_type_bound(ctx, bound, tr)),
454 ) 569 )
455 } 570 }
456} 571}
457 572
458fn assoc_type_bindings_from_type_bound<'a>( 573fn assoc_type_bindings_from_type_bound<'a>(
459 db: &'a impl HirDatabase, 574 ctx: &'a TyLoweringContext<'a, impl HirDatabase>,
460 resolver: &'a Resolver,
461 bound: &'a TypeBound, 575 bound: &'a TypeBound,
462 trait_ref: TraitRef, 576 trait_ref: TraitRef,
463) -> impl Iterator<Item = GenericPredicate> + 'a { 577) -> impl Iterator<Item = GenericPredicate> + 'a {
@@ -471,21 +585,21 @@ fn assoc_type_bindings_from_type_bound<'a>(
471 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) 585 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter())
472 .map(move |(name, type_ref)| { 586 .map(move |(name, type_ref)| {
473 let associated_ty = 587 let associated_ty =
474 associated_type_by_name_including_super_traits(db, trait_ref.trait_, &name); 588 associated_type_by_name_including_super_traits(ctx.db, trait_ref.trait_, &name);
475 let associated_ty = match associated_ty { 589 let associated_ty = match associated_ty {
476 None => return GenericPredicate::Error, 590 None => return GenericPredicate::Error,
477 Some(t) => t, 591 Some(t) => t,
478 }; 592 };
479 let projection_ty = 593 let projection_ty =
480 ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() }; 594 ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() };
481 let ty = Ty::from_hir(db, resolver, type_ref); 595 let ty = Ty::from_hir(ctx, type_ref);
482 let projection_predicate = ProjectionPredicate { projection_ty, ty }; 596 let projection_predicate = ProjectionPredicate { projection_ty, ty };
483 GenericPredicate::Projection(projection_predicate) 597 GenericPredicate::Projection(projection_predicate)
484 }) 598 })
485} 599}
486 600
487/// Build the signature of a callable item (function, struct or enum variant). 601/// Build the signature of a callable item (function, struct or enum variant).
488pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { 602pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> PolyFnSig {
489 match def { 603 match def {
490 CallableDef::FunctionId(f) => fn_sig_for_fn(db, f), 604 CallableDef::FunctionId(f) => fn_sig_for_fn(db, f),
491 CallableDef::StructId(s) => fn_sig_for_struct_constructor(db, s), 605 CallableDef::StructId(s) => fn_sig_for_struct_constructor(db, s),
@@ -497,16 +611,19 @@ pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig {
497pub(crate) fn field_types_query( 611pub(crate) fn field_types_query(
498 db: &impl HirDatabase, 612 db: &impl HirDatabase,
499 variant_id: VariantId, 613 variant_id: VariantId,
500) -> Arc<ArenaMap<LocalStructFieldId, Ty>> { 614) -> Arc<ArenaMap<LocalStructFieldId, Binders<Ty>>> {
501 let var_data = variant_data(db, variant_id); 615 let var_data = variant_data(db, variant_id);
502 let resolver = match variant_id { 616 let (resolver, def): (_, GenericDefId) = match variant_id {
503 VariantId::StructId(it) => it.resolver(db), 617 VariantId::StructId(it) => (it.resolver(db), it.into()),
504 VariantId::UnionId(it) => it.resolver(db), 618 VariantId::UnionId(it) => (it.resolver(db), it.into()),
505 VariantId::EnumVariantId(it) => it.parent.resolver(db), 619 VariantId::EnumVariantId(it) => (it.parent.resolver(db), it.parent.into()),
506 }; 620 };
621 let generics = generics(db, def);
507 let mut res = ArenaMap::default(); 622 let mut res = ArenaMap::default();
623 let ctx =
624 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
508 for (field_id, field_data) in var_data.fields().iter() { 625 for (field_id, field_data) in var_data.fields().iter() {
509 res.insert(field_id, Ty::from_hir(db, &resolver, &field_data.type_ref)) 626 res.insert(field_id, Binders::new(generics.len(), Ty::from_hir(&ctx, &field_data.type_ref)))
510 } 627 }
511 Arc::new(res) 628 Arc::new(res)
512} 629}
@@ -521,32 +638,43 @@ pub(crate) fn field_types_query(
521/// these are fine: `T: Foo<U::Item>, U: Foo<()>`. 638/// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
522pub(crate) fn generic_predicates_for_param_query( 639pub(crate) fn generic_predicates_for_param_query(
523 db: &impl HirDatabase, 640 db: &impl HirDatabase,
524 def: GenericDefId, 641 param_id: TypeParamId,
525 param_idx: u32, 642) -> Arc<[Binders<GenericPredicate>]> {
526) -> Arc<[GenericPredicate]> { 643 let resolver = param_id.parent.resolver(db);
527 let resolver = def.resolver(db); 644 let ctx =
645 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
646 let generics = generics(db, param_id.parent);
528 resolver 647 resolver
529 .where_predicates_in_scope() 648 .where_predicates_in_scope()
530 // we have to filter out all other predicates *first*, before attempting to lower them 649 // we have to filter out all other predicates *first*, before attempting to lower them
531 .filter(|pred| Ty::from_hir_only_param(db, &resolver, &pred.type_ref) == Some(param_idx)) 650 .filter(|pred| match &pred.target {
532 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 651 WherePredicateTarget::TypeRef(type_ref) => {
652 Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id)
653 }
654 WherePredicateTarget::TypeParam(local_id) => *local_id == param_id.local_id,
655 })
656 .flat_map(|pred| {
657 GenericPredicate::from_where_predicate(&ctx, pred)
658 .map(|p| Binders::new(generics.len(), p))
659 })
533 .collect() 660 .collect()
534} 661}
535 662
536pub(crate) fn generic_predicates_for_param_recover( 663pub(crate) fn generic_predicates_for_param_recover(
537 _db: &impl HirDatabase, 664 _db: &impl HirDatabase,
538 _cycle: &[String], 665 _cycle: &[String],
539 _def: &GenericDefId, 666 _param_id: &TypeParamId,
540 _param_idx: &u32, 667) -> Arc<[Binders<GenericPredicate>]> {
541) -> Arc<[GenericPredicate]> {
542 Arc::new([]) 668 Arc::new([])
543} 669}
544 670
545impl TraitEnvironment { 671impl TraitEnvironment {
546 pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { 672 pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> {
673 let ctx = TyLoweringContext::new(db, &resolver)
674 .with_type_param_mode(TypeParamLoweringMode::Placeholder);
547 let predicates = resolver 675 let predicates = resolver
548 .where_predicates_in_scope() 676 .where_predicates_in_scope()
549 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 677 .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred))
550 .collect::<Vec<_>>(); 678 .collect::<Vec<_>>();
551 679
552 Arc::new(TraitEnvironment { predicates }) 680 Arc::new(TraitEnvironment { predicates })
@@ -557,57 +685,74 @@ impl TraitEnvironment {
557pub(crate) fn generic_predicates_query( 685pub(crate) fn generic_predicates_query(
558 db: &impl HirDatabase, 686 db: &impl HirDatabase,
559 def: GenericDefId, 687 def: GenericDefId,
560) -> Arc<[GenericPredicate]> { 688) -> Arc<[Binders<GenericPredicate>]> {
561 let resolver = def.resolver(db); 689 let resolver = def.resolver(db);
690 let ctx =
691 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
692 let generics = generics(db, def);
562 resolver 693 resolver
563 .where_predicates_in_scope() 694 .where_predicates_in_scope()
564 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 695 .flat_map(|pred| {
696 GenericPredicate::from_where_predicate(&ctx, pred)
697 .map(|p| Binders::new(generics.len(), p))
698 })
565 .collect() 699 .collect()
566} 700}
567 701
568/// Resolve the default type params from generics 702/// Resolve the default type params from generics
569pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs { 703pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs {
570 let resolver = def.resolver(db); 704 let resolver = def.resolver(db);
705 let ctx = TyLoweringContext::new(db, &resolver);
571 let generic_params = generics(db, def.into()); 706 let generic_params = generics(db, def.into());
572 707
573 let defaults = generic_params 708 let defaults = generic_params
574 .iter() 709 .iter()
575 .map(|(_idx, p)| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(db, &resolver, t))) 710 .map(|(_idx, p)| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(&ctx, t)))
576 .collect(); 711 .collect();
577 712
578 Substs(defaults) 713 Substs(defaults)
579} 714}
580 715
581fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { 716fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> PolyFnSig {
582 let data = db.function_data(def); 717 let data = db.function_data(def);
583 let resolver = def.resolver(db); 718 let resolver = def.resolver(db);
584 let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); 719 let ctx_params = TyLoweringContext::new(db, &resolver)
585 let ret = Ty::from_hir(db, &resolver, &data.ret_type); 720 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
586 FnSig::from_params_and_return(params, ret) 721 .with_type_param_mode(TypeParamLoweringMode::Variable);
722 let params = data.params.iter().map(|tr| Ty::from_hir(&ctx_params, tr)).collect::<Vec<_>>();
723 let ctx_ret = ctx_params.with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
724 let ret = Ty::from_hir(&ctx_ret, &data.ret_type);
725 let generics = generics(db, def.into());
726 let num_binders = generics.len();
727 Binders::new(num_binders, FnSig::from_params_and_return(params, ret))
587} 728}
588 729
589/// Build the declared type of a function. This should not need to look at the 730/// Build the declared type of a function. This should not need to look at the
590/// function body. 731/// function body.
591fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty { 732fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Binders<Ty> {
592 let generics = generics(db, def.into()); 733 let generics = generics(db, def.into());
593 let substs = Substs::identity(&generics); 734 let substs = Substs::bound_vars(&generics);
594 Ty::apply(TypeCtor::FnDef(def.into()), substs) 735 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs))
595} 736}
596 737
597/// Build the declared type of a const. 738/// Build the declared type of a const.
598fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Ty { 739fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Binders<Ty> {
599 let data = db.const_data(def); 740 let data = db.const_data(def);
741 let generics = generics(db, def.into());
600 let resolver = def.resolver(db); 742 let resolver = def.resolver(db);
743 let ctx =
744 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
601 745
602 Ty::from_hir(db, &resolver, &data.type_ref) 746 Binders::new(generics.len(), Ty::from_hir(&ctx, &data.type_ref))
603} 747}
604 748
605/// Build the declared type of a static. 749/// Build the declared type of a static.
606fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Ty { 750fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Binders<Ty> {
607 let data = db.static_data(def); 751 let data = db.static_data(def);
608 let resolver = def.resolver(db); 752 let resolver = def.resolver(db);
753 let ctx = TyLoweringContext::new(db, &resolver);
609 754
610 Ty::from_hir(db, &resolver, &data.type_ref) 755 Binders::new(0, Ty::from_hir(&ctx, &data.type_ref))
611} 756}
612 757
613/// Build the declared type of a static. 758/// Build the declared type of a static.
@@ -621,68 +766,69 @@ fn type_for_builtin(def: BuiltinType) -> Ty {
621 }) 766 })
622} 767}
623 768
624fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig { 769fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> PolyFnSig {
625 let struct_data = db.struct_data(def.into()); 770 let struct_data = db.struct_data(def.into());
626 let fields = struct_data.variant_data.fields(); 771 let fields = struct_data.variant_data.fields();
627 let resolver = def.resolver(db); 772 let resolver = def.resolver(db);
628 let params = fields 773 let ctx =
629 .iter() 774 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
630 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 775 let params =
631 .collect::<Vec<_>>(); 776 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
632 let ret = type_for_adt(db, def.into()); 777 let ret = type_for_adt(db, def.into());
633 FnSig::from_params_and_return(params, ret) 778 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value))
634} 779}
635 780
636/// Build the type of a tuple struct constructor. 781/// Build the type of a tuple struct constructor.
637fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Ty { 782fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Binders<Ty> {
638 let struct_data = db.struct_data(def.into()); 783 let struct_data = db.struct_data(def.into());
639 if struct_data.variant_data.is_unit() { 784 if struct_data.variant_data.is_unit() {
640 return type_for_adt(db, def.into()); // Unit struct 785 return type_for_adt(db, def.into()); // Unit struct
641 } 786 }
642 let generics = generics(db, def.into()); 787 let generics = generics(db, def.into());
643 let substs = Substs::identity(&generics); 788 let substs = Substs::bound_vars(&generics);
644 Ty::apply(TypeCtor::FnDef(def.into()), substs) 789 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs))
645} 790}
646 791
647fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig { 792fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> PolyFnSig {
648 let enum_data = db.enum_data(def.parent); 793 let enum_data = db.enum_data(def.parent);
649 let var_data = &enum_data.variants[def.local_id]; 794 let var_data = &enum_data.variants[def.local_id];
650 let fields = var_data.variant_data.fields(); 795 let fields = var_data.variant_data.fields();
651 let resolver = def.parent.resolver(db); 796 let resolver = def.parent.resolver(db);
652 let params = fields 797 let ctx =
653 .iter() 798 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
654 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 799 let params =
655 .collect::<Vec<_>>(); 800 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
656 let generics = generics(db, def.parent.into()); 801 let ret = type_for_adt(db, def.parent.into());
657 let substs = Substs::identity(&generics); 802 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value))
658 let ret = type_for_adt(db, def.parent.into()).subst(&substs);
659 FnSig::from_params_and_return(params, ret)
660} 803}
661 804
662/// Build the type of a tuple enum variant constructor. 805/// Build the type of a tuple enum variant constructor.
663fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Ty { 806fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Binders<Ty> {
664 let enum_data = db.enum_data(def.parent); 807 let enum_data = db.enum_data(def.parent);
665 let var_data = &enum_data.variants[def.local_id].variant_data; 808 let var_data = &enum_data.variants[def.local_id].variant_data;
666 if var_data.is_unit() { 809 if var_data.is_unit() {
667 return type_for_adt(db, def.parent.into()); // Unit variant 810 return type_for_adt(db, def.parent.into()); // Unit variant
668 } 811 }
669 let generics = generics(db, def.parent.into()); 812 let generics = generics(db, def.parent.into());
670 let substs = Substs::identity(&generics); 813 let substs = Substs::bound_vars(&generics);
671 Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) 814 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs))
672} 815}
673 816
674fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty { 817fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Binders<Ty> {
675 let generics = generics(db, adt.into()); 818 let generics = generics(db, adt.into());
676 Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) 819 let substs = Substs::bound_vars(&generics);
820 Binders::new(substs.len(), Ty::apply(TypeCtor::Adt(adt), substs))
677} 821}
678 822
679fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { 823fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Binders<Ty> {
680 let generics = generics(db, t.into()); 824 let generics = generics(db, t.into());
681 let resolver = t.resolver(db); 825 let resolver = t.resolver(db);
826 let ctx =
827 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
682 let type_ref = &db.type_alias_data(t).type_ref; 828 let type_ref = &db.type_alias_data(t).type_ref;
683 let substs = Substs::identity(&generics); 829 let substs = Substs::bound_vars(&generics);
684 let inner = Ty::from_hir(db, &resolver, type_ref.as_ref().unwrap_or(&TypeRef::Error)); 830 let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error));
685 inner.subst(&substs) 831 Binders::new(substs.len(), inner)
686} 832}
687 833
688#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 834#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -736,19 +882,24 @@ impl_froms!(ValueTyDefId: FunctionId, StructId, EnumVariantId, ConstId, StaticId
736/// `struct Foo(usize)`, we have two types: The type of the struct itself, and 882/// `struct Foo(usize)`, we have two types: The type of the struct itself, and
737/// the constructor function `(usize) -> Foo` which lives in the values 883/// the constructor function `(usize) -> Foo` which lives in the values
738/// namespace. 884/// namespace.
739pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Ty { 885pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Binders<Ty> {
740 match def { 886 match def {
741 TyDefId::BuiltinType(it) => type_for_builtin(it), 887 TyDefId::BuiltinType(it) => Binders::new(0, type_for_builtin(it)),
742 TyDefId::AdtId(it) => type_for_adt(db, it), 888 TyDefId::AdtId(it) => type_for_adt(db, it),
743 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), 889 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
744 } 890 }
745} 891}
746 892
747pub(crate) fn ty_recover(_db: &impl HirDatabase, _cycle: &[String], _def: &TyDefId) -> Ty { 893pub(crate) fn ty_recover(db: &impl HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> {
748 Ty::Unknown 894 let num_binders = match *def {
895 TyDefId::BuiltinType(_) => 0,
896 TyDefId::AdtId(it) => generics(db, it.into()).len(),
897 TyDefId::TypeAliasId(it) => generics(db, it.into()).len(),
898 };
899 Binders::new(num_binders, Ty::Unknown)
749} 900}
750 901
751pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { 902pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
752 match def { 903 match def {
753 ValueTyDefId::FunctionId(it) => type_for_fn(db, it), 904 ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
754 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it), 905 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
@@ -758,24 +909,36 @@ pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty {
758 } 909 }
759} 910}
760 911
761pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Ty { 912pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Binders<Ty> {
762 let impl_data = db.impl_data(impl_id); 913 let impl_data = db.impl_data(impl_id);
763 let resolver = impl_id.resolver(db); 914 let resolver = impl_id.resolver(db);
764 Ty::from_hir(db, &resolver, &impl_data.target_type) 915 let generics = generics(db, impl_id.into());
916 let ctx =
917 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
918 Binders::new(generics.len(), Ty::from_hir(&ctx, &impl_data.target_type))
765} 919}
766 920
767pub(crate) fn impl_self_ty_recover( 921pub(crate) fn impl_self_ty_recover(
768 _db: &impl HirDatabase, 922 db: &impl HirDatabase,
769 _cycle: &[String], 923 _cycle: &[String],
770 _impl_id: &ImplId, 924 impl_id: &ImplId,
771) -> Ty { 925) -> Binders<Ty> {
772 Ty::Unknown 926 let generics = generics(db, (*impl_id).into());
927 Binders::new(generics.len(), Ty::Unknown)
773} 928}
774 929
775pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<TraitRef> { 930pub(crate) fn impl_trait_query(
931 db: &impl HirDatabase,
932 impl_id: ImplId,
933) -> Option<Binders<TraitRef>> {
776 let impl_data = db.impl_data(impl_id); 934 let impl_data = db.impl_data(impl_id);
777 let resolver = impl_id.resolver(db); 935 let resolver = impl_id.resolver(db);
936 let ctx =
937 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
778 let self_ty = db.impl_self_ty(impl_id); 938 let self_ty = db.impl_self_ty(impl_id);
779 let target_trait = impl_data.target_trait.as_ref()?; 939 let target_trait = impl_data.target_trait.as_ref()?;
780 TraitRef::from_hir(db, &resolver, target_trait, Some(self_ty.clone())) 940 Some(Binders::new(
941 self_ty.num_binders,
942 TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value.clone()))?,
943 ))
781} 944}
diff --git a/crates/ra_hir_ty/src/marks.rs b/crates/ra_hir_ty/src/marks.rs
index fe74acf11..0f754eb9c 100644
--- a/crates/ra_hir_ty/src/marks.rs
+++ b/crates/ra_hir_ty/src/marks.rs
@@ -6,5 +6,4 @@ test_utils::marks!(
6 type_var_resolves_to_int_var 6 type_var_resolves_to_int_var
7 match_ergonomics_ref 7 match_ergonomics_ref
8 coerce_merge_fail_fallback 8 coerce_merge_fail_fallback
9 insert_vars_for_impl_trait
10); 9);
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 5bacbbd7c..5283bff28 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -61,11 +61,11 @@ impl CrateImplBlocks {
61 for impl_id in module_data.scope.impls() { 61 for impl_id in module_data.scope.impls() {
62 match db.impl_trait(impl_id) { 62 match db.impl_trait(impl_id) {
63 Some(tr) => { 63 Some(tr) => {
64 res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id); 64 res.impls_by_trait.entry(tr.value.trait_).or_default().push(impl_id);
65 } 65 }
66 None => { 66 None => {
67 let self_ty = db.impl_self_ty(impl_id); 67 let self_ty = db.impl_self_ty(impl_id);
68 if let Some(self_ty_fp) = TyFingerprint::for_impl(&self_ty) { 68 if let Some(self_ty_fp) = TyFingerprint::for_impl(&self_ty.value) {
69 res.impls.entry(self_ty_fp).or_default().push(impl_id); 69 res.impls.entry(self_ty_fp).or_default().push(impl_id);
70 } 70 }
71 } 71 }
@@ -496,7 +496,7 @@ fn transform_receiver_ty(
496 AssocContainerId::ContainerId(_) => unreachable!(), 496 AssocContainerId::ContainerId(_) => unreachable!(),
497 }; 497 };
498 let sig = db.callable_item_signature(function_id.into()); 498 let sig = db.callable_item_signature(function_id.into());
499 Some(sig.params()[0].clone().subst(&substs)) 499 Some(sig.value.params()[0].clone().subst_bound_vars(&substs))
500} 500}
501 501
502pub fn implements_trait( 502pub fn implements_trait(
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs
index 76a1b46c0..fc5ef36a5 100644
--- a/crates/ra_hir_ty/src/tests/coercion.rs
+++ b/crates/ra_hir_ty/src/tests/coercion.rs
@@ -75,7 +75,7 @@ fn test2() {
75 [124; 131) 'loop {}': ! 75 [124; 131) 'loop {}': !
76 [129; 131) '{}': () 76 [129; 131) '{}': ()
77 [160; 173) '{ gen() }': *mut [U] 77 [160; 173) '{ gen() }': *mut [U]
78 [166; 169) 'gen': fn gen<U>() -> *mut [T; _] 78 [166; 169) 'gen': fn gen<U>() -> *mut [U; _]
79 [166; 171) 'gen()': *mut [U; _] 79 [166; 171) 'gen()': *mut [U; _]
80 [186; 420) '{ ...rr); }': () 80 [186; 420) '{ ...rr); }': ()
81 [196; 199) 'arr': &[u8; _] 81 [196; 199) 'arr': &[u8; _]
@@ -85,14 +85,14 @@ fn test2() {
85 [227; 228) 'a': &[u8] 85 [227; 228) 'a': &[u8]
86 [237; 240) 'arr': &[u8; _] 86 [237; 240) 'arr': &[u8; _]
87 [250; 251) 'b': u8 87 [250; 251) 'b': u8
88 [254; 255) 'f': fn f<u8>(&[T]) -> T 88 [254; 255) 'f': fn f<u8>(&[u8]) -> u8
89 [254; 260) 'f(arr)': u8 89 [254; 260) 'f(arr)': u8
90 [256; 259) 'arr': &[u8; _] 90 [256; 259) 'arr': &[u8; _]
91 [270; 271) 'c': &[u8] 91 [270; 271) 'c': &[u8]
92 [280; 287) '{ arr }': &[u8] 92 [280; 287) '{ arr }': &[u8]
93 [282; 285) 'arr': &[u8; _] 93 [282; 285) 'arr': &[u8; _]
94 [297; 298) 'd': u8 94 [297; 298) 'd': u8
95 [301; 302) 'g': fn g<u8>(S<&[T]>) -> T 95 [301; 302) 'g': fn g<u8>(S<&[u8]>) -> u8
96 [301; 316) 'g(S { a: arr })': u8 96 [301; 316) 'g(S { a: arr })': u8
97 [303; 315) 'S { a: arr }': S<&[u8]> 97 [303; 315) 'S { a: arr }': S<&[u8]>
98 [310; 313) 'arr': &[u8; _] 98 [310; 313) 'arr': &[u8; _]
@@ -164,15 +164,15 @@ fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) {
164 [400; 401) 'c': C<[u8; _]> 164 [400; 401) 'c': C<[u8; _]>
165 [415; 481) '{ ...(c); }': () 165 [415; 481) '{ ...(c); }': ()
166 [425; 426) 'd': A<[{unknown}]> 166 [425; 426) 'd': A<[{unknown}]>
167 [429; 433) 'foo1': fn foo1<{unknown}>(A<[T]>) -> A<[T]> 167 [429; 433) 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]>
168 [429; 436) 'foo1(a)': A<[{unknown}]> 168 [429; 436) 'foo1(a)': A<[{unknown}]>
169 [434; 435) 'a': A<[u8; _]> 169 [434; 435) 'a': A<[u8; _]>
170 [446; 447) 'e': B<[u8]> 170 [446; 447) 'e': B<[u8]>
171 [450; 454) 'foo2': fn foo2<u8>(B<[T]>) -> B<[T]> 171 [450; 454) 'foo2': fn foo2<u8>(B<[u8]>) -> B<[u8]>
172 [450; 457) 'foo2(b)': B<[u8]> 172 [450; 457) 'foo2(b)': B<[u8]>
173 [455; 456) 'b': B<[u8; _]> 173 [455; 456) 'b': B<[u8; _]>
174 [467; 468) 'f': C<[u8]> 174 [467; 468) 'f': C<[u8]>
175 [471; 475) 'foo3': fn foo3<u8>(C<[T]>) -> C<[T]> 175 [471; 475) 'foo3': fn foo3<u8>(C<[u8]>) -> C<[u8]>
176 [471; 478) 'foo3(c)': C<[u8]> 176 [471; 478) 'foo3(c)': C<[u8]>
177 [476; 477) 'c': C<[u8; _]> 177 [476; 477) 'c': C<[u8; _]>
178 "### 178 "###
@@ -202,7 +202,7 @@ fn test() {
202 [64; 123) 'if tru... }': &[i32] 202 [64; 123) 'if tru... }': &[i32]
203 [67; 71) 'true': bool 203 [67; 71) 'true': bool
204 [72; 97) '{ ... }': &[i32] 204 [72; 97) '{ ... }': &[i32]
205 [82; 85) 'foo': fn foo<i32>(&[T]) -> &[T] 205 [82; 85) 'foo': fn foo<i32>(&[i32]) -> &[i32]
206 [82; 91) 'foo(&[1])': &[i32] 206 [82; 91) 'foo(&[1])': &[i32]
207 [86; 90) '&[1]': &[i32; _] 207 [86; 90) '&[1]': &[i32; _]
208 [87; 90) '[1]': [i32; _] 208 [87; 90) '[1]': [i32; _]
@@ -242,7 +242,7 @@ fn test() {
242 [83; 86) '[1]': [i32; _] 242 [83; 86) '[1]': [i32; _]
243 [84; 85) '1': i32 243 [84; 85) '1': i32
244 [98; 123) '{ ... }': &[i32] 244 [98; 123) '{ ... }': &[i32]
245 [108; 111) 'foo': fn foo<i32>(&[T]) -> &[T] 245 [108; 111) 'foo': fn foo<i32>(&[i32]) -> &[i32]
246 [108; 117) 'foo(&[1])': &[i32] 246 [108; 117) 'foo(&[1])': &[i32]
247 [112; 116) '&[1]': &[i32; _] 247 [112; 116) '&[1]': &[i32; _]
248 [113; 116) '[1]': [i32; _] 248 [113; 116) '[1]': [i32; _]
@@ -275,7 +275,7 @@ fn test(i: i32) {
275 [70; 147) 'match ... }': &[i32] 275 [70; 147) 'match ... }': &[i32]
276 [76; 77) 'i': i32 276 [76; 77) 'i': i32
277 [88; 89) '2': i32 277 [88; 89) '2': i32
278 [93; 96) 'foo': fn foo<i32>(&[T]) -> &[T] 278 [93; 96) 'foo': fn foo<i32>(&[i32]) -> &[i32]
279 [93; 102) 'foo(&[2])': &[i32] 279 [93; 102) 'foo(&[2])': &[i32]
280 [97; 101) '&[2]': &[i32; _] 280 [97; 101) '&[2]': &[i32; _]
281 [98; 101) '[2]': [i32; _] 281 [98; 101) '[2]': [i32; _]
@@ -320,7 +320,7 @@ fn test(i: i32) {
320 [94; 97) '[1]': [i32; _] 320 [94; 97) '[1]': [i32; _]
321 [95; 96) '1': i32 321 [95; 96) '1': i32
322 [107; 108) '2': i32 322 [107; 108) '2': i32
323 [112; 115) 'foo': fn foo<i32>(&[T]) -> &[T] 323 [112; 115) 'foo': fn foo<i32>(&[i32]) -> &[i32]
324 [112; 121) 'foo(&[2])': &[i32] 324 [112; 121) 'foo(&[2])': &[i32]
325 [116; 120) '&[2]': &[i32; _] 325 [116; 120) '&[2]': &[i32; _]
326 [117; 120) '[2]': [i32; _] 326 [117; 120) '[2]': [i32; _]
@@ -438,16 +438,16 @@ fn test() {
438 [43; 45) '*x': T 438 [43; 45) '*x': T
439 [44; 45) 'x': &T 439 [44; 45) 'x': &T
440 [58; 127) '{ ...oo); }': () 440 [58; 127) '{ ...oo); }': ()
441 [64; 73) 'takes_ref': fn takes_ref<Foo>(&T) -> T 441 [64; 73) 'takes_ref': fn takes_ref<Foo>(&Foo) -> Foo
442 [64; 79) 'takes_ref(&Foo)': Foo 442 [64; 79) 'takes_ref(&Foo)': Foo
443 [74; 78) '&Foo': &Foo 443 [74; 78) '&Foo': &Foo
444 [75; 78) 'Foo': Foo 444 [75; 78) 'Foo': Foo
445 [85; 94) 'takes_ref': fn takes_ref<&Foo>(&T) -> T 445 [85; 94) 'takes_ref': fn takes_ref<&Foo>(&&Foo) -> &Foo
446 [85; 101) 'takes_...&&Foo)': &Foo 446 [85; 101) 'takes_...&&Foo)': &Foo
447 [95; 100) '&&Foo': &&Foo 447 [95; 100) '&&Foo': &&Foo
448 [96; 100) '&Foo': &Foo 448 [96; 100) '&Foo': &Foo
449 [97; 100) 'Foo': Foo 449 [97; 100) 'Foo': Foo
450 [107; 116) 'takes_ref': fn takes_ref<&&Foo>(&T) -> T 450 [107; 116) 'takes_ref': fn takes_ref<&&Foo>(&&&Foo) -> &&Foo
451 [107; 124) 'takes_...&&Foo)': &&Foo 451 [107; 124) 'takes_...&&Foo)': &&Foo
452 [117; 123) '&&&Foo': &&&Foo 452 [117; 123) '&&&Foo': &&&Foo
453 [118; 123) '&&Foo': &&Foo 453 [118; 123) '&&Foo': &&Foo
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs
index ce9a06fde..1722563aa 100644
--- a/crates/ra_hir_ty/src/tests/method_resolution.rs
+++ b/crates/ra_hir_ty/src/tests/method_resolution.rs
@@ -27,7 +27,7 @@ fn test() {
27 [66; 73) 'loop {}': ! 27 [66; 73) 'loop {}': !
28 [71; 73) '{}': () 28 [71; 73) '{}': ()
29 [133; 160) '{ ...o"); }': () 29 [133; 160) '{ ...o"); }': ()
30 [139; 149) '<[_]>::foo': fn foo<u8>(&[T]) -> T 30 [139; 149) '<[_]>::foo': fn foo<u8>(&[u8]) -> u8
31 [139; 157) '<[_]>:..."foo")': u8 31 [139; 157) '<[_]>:..."foo")': u8
32 [150; 156) 'b"foo"': &[u8] 32 [150; 156) 'b"foo"': &[u8]
33 "### 33 "###
@@ -175,7 +175,7 @@ fn test() {
175 [98; 101) 'val': T 175 [98; 101) 'val': T
176 [123; 155) '{ ...32); }': () 176 [123; 155) '{ ...32); }': ()
177 [133; 134) 'a': Gen<u32> 177 [133; 134) 'a': Gen<u32>
178 [137; 146) 'Gen::make': fn make<u32>(T) -> Gen<T> 178 [137; 146) 'Gen::make': fn make<u32>(u32) -> Gen<u32>
179 [137; 152) 'Gen::make(0u32)': Gen<u32> 179 [137; 152) 'Gen::make(0u32)': Gen<u32>
180 [147; 151) '0u32': u32 180 [147; 151) '0u32': u32
181 "### 181 "###
@@ -206,7 +206,7 @@ fn test() {
206 [95; 98) '{ }': () 206 [95; 98) '{ }': ()
207 [118; 146) '{ ...e(); }': () 207 [118; 146) '{ ...e(); }': ()
208 [128; 129) 'a': Gen<u32> 208 [128; 129) 'a': Gen<u32>
209 [132; 141) 'Gen::make': fn make<u32>() -> Gen<T> 209 [132; 141) 'Gen::make': fn make<u32>() -> Gen<u32>
210 [132; 143) 'Gen::make()': Gen<u32> 210 [132; 143) 'Gen::make()': Gen<u32>
211 "### 211 "###
212 ); 212 );
@@ -260,7 +260,7 @@ fn test() {
260 [91; 94) '{ }': () 260 [91; 94) '{ }': ()
261 [114; 149) '{ ...e(); }': () 261 [114; 149) '{ ...e(); }': ()
262 [124; 125) 'a': Gen<u32> 262 [124; 125) 'a': Gen<u32>
263 [128; 144) 'Gen::<...::make': fn make<u32>() -> Gen<T> 263 [128; 144) 'Gen::<...::make': fn make<u32>() -> Gen<u32>
264 [128; 146) 'Gen::<...make()': Gen<u32> 264 [128; 146) 'Gen::<...make()': Gen<u32>
265 "### 265 "###
266 ); 266 );
@@ -291,7 +291,7 @@ fn test() {
291 [117; 120) '{ }': () 291 [117; 120) '{ }': ()
292 [140; 180) '{ ...e(); }': () 292 [140; 180) '{ ...e(); }': ()
293 [150; 151) 'a': Gen<u32, u64> 293 [150; 151) 'a': Gen<u32, u64>
294 [154; 175) 'Gen::<...::make': fn make<u64>() -> Gen<u32, T> 294 [154; 175) 'Gen::<...::make': fn make<u64>() -> Gen<u32, u64>
295 [154; 177) 'Gen::<...make()': Gen<u32, u64> 295 [154; 177) 'Gen::<...make()': Gen<u32, u64>
296 "### 296 "###
297 ); 297 );
@@ -475,7 +475,7 @@ fn test() {
475 @r###" 475 @r###"
476 [33; 37) 'self': &Self 476 [33; 37) 'self': &Self
477 [102; 127) '{ ...d(); }': () 477 [102; 127) '{ ...d(); }': ()
478 [108; 109) 'S': S<u32>(T) -> S<T> 478 [108; 109) 'S': S<u32>(u32) -> S<u32>
479 [108; 115) 'S(1u32)': S<u32> 479 [108; 115) 'S(1u32)': S<u32>
480 [108; 124) 'S(1u32...thod()': u32 480 [108; 124) 'S(1u32...thod()': u32
481 [110; 114) '1u32': u32 481 [110; 114) '1u32': u32
@@ -501,13 +501,13 @@ fn test() {
501 @r###" 501 @r###"
502 [87; 193) '{ ...t(); }': () 502 [87; 193) '{ ...t(); }': ()
503 [97; 99) 's1': S 503 [97; 99) 's1': S
504 [105; 121) 'Defaul...efault': fn default<S>() -> Self 504 [105; 121) 'Defaul...efault': fn default<S>() -> S
505 [105; 123) 'Defaul...ault()': S 505 [105; 123) 'Defaul...ault()': S
506 [133; 135) 's2': S 506 [133; 135) 's2': S
507 [138; 148) 'S::default': fn default<S>() -> Self 507 [138; 148) 'S::default': fn default<S>() -> S
508 [138; 150) 'S::default()': S 508 [138; 150) 'S::default()': S
509 [160; 162) 's3': S 509 [160; 162) 's3': S
510 [165; 188) '<S as ...efault': fn default<S>() -> Self 510 [165; 188) '<S as ...efault': fn default<S>() -> S
511 [165; 190) '<S as ...ault()': S 511 [165; 190) '<S as ...ault()': S
512 "### 512 "###
513 ); 513 );
@@ -533,13 +533,13 @@ fn test() {
533 @r###" 533 @r###"
534 [127; 211) '{ ...e(); }': () 534 [127; 211) '{ ...e(); }': ()
535 [137; 138) 'a': u32 535 [137; 138) 'a': u32
536 [141; 148) 'S::make': fn make<S, u32>() -> T 536 [141; 148) 'S::make': fn make<S, u32>() -> u32
537 [141; 150) 'S::make()': u32 537 [141; 150) 'S::make()': u32
538 [160; 161) 'b': u64 538 [160; 161) 'b': u64
539 [164; 178) 'G::<u64>::make': fn make<G<u64>, u64>() -> T 539 [164; 178) 'G::<u64>::make': fn make<G<u64>, u64>() -> u64
540 [164; 180) 'G::<u6...make()': u64 540 [164; 180) 'G::<u6...make()': u64
541 [190; 191) 'c': f64 541 [190; 191) 'c': f64
542 [199; 206) 'G::make': fn make<G<f64>, f64>() -> T 542 [199; 206) 'G::make': fn make<G<f64>, f64>() -> f64
543 [199; 208) 'G::make()': f64 543 [199; 208) 'G::make()': f64
544 "### 544 "###
545 ); 545 );
@@ -567,19 +567,19 @@ fn test() {
567 @r###" 567 @r###"
568 [135; 313) '{ ...e(); }': () 568 [135; 313) '{ ...e(); }': ()
569 [145; 146) 'a': (u32, i64) 569 [145; 146) 'a': (u32, i64)
570 [149; 163) 'S::make::<i64>': fn make<S, u32, i64>() -> (T, U) 570 [149; 163) 'S::make::<i64>': fn make<S, u32, i64>() -> (u32, i64)
571 [149; 165) 'S::mak...i64>()': (u32, i64) 571 [149; 165) 'S::mak...i64>()': (u32, i64)
572 [175; 176) 'b': (u32, i64) 572 [175; 176) 'b': (u32, i64)
573 [189; 196) 'S::make': fn make<S, u32, i64>() -> (T, U) 573 [189; 196) 'S::make': fn make<S, u32, i64>() -> (u32, i64)
574 [189; 198) 'S::make()': (u32, i64) 574 [189; 198) 'S::make()': (u32, i64)
575 [208; 209) 'c': (u32, i64) 575 [208; 209) 'c': (u32, i64)
576 [212; 233) 'G::<u3...:<i64>': fn make<G<u32>, u32, i64>() -> (T, U) 576 [212; 233) 'G::<u3...:<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64)
577 [212; 235) 'G::<u3...i64>()': (u32, i64) 577 [212; 235) 'G::<u3...i64>()': (u32, i64)
578 [245; 246) 'd': (u32, i64) 578 [245; 246) 'd': (u32, i64)
579 [259; 273) 'G::make::<i64>': fn make<G<u32>, u32, i64>() -> (T, U) 579 [259; 273) 'G::make::<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64)
580 [259; 275) 'G::mak...i64>()': (u32, i64) 580 [259; 275) 'G::mak...i64>()': (u32, i64)
581 [285; 286) 'e': (u32, i64) 581 [285; 286) 'e': (u32, i64)
582 [301; 308) 'G::make': fn make<G<u32>, u32, i64>() -> (T, U) 582 [301; 308) 'G::make': fn make<G<u32>, u32, i64>() -> (u32, i64)
583 [301; 310) 'G::make()': (u32, i64) 583 [301; 310) 'G::make()': (u32, i64)
584 "### 584 "###
585 ); 585 );
@@ -601,7 +601,7 @@ fn test() {
601 @r###" 601 @r###"
602 [101; 127) '{ ...e(); }': () 602 [101; 127) '{ ...e(); }': ()
603 [111; 112) 'a': (S<i32>, i64) 603 [111; 112) 'a': (S<i32>, i64)
604 [115; 122) 'S::make': fn make<S<i32>, i64>() -> (Self, T) 604 [115; 122) 'S::make': fn make<S<i32>, i64>() -> (S<i32>, i64)
605 [115; 124) 'S::make()': (S<i32>, i64) 605 [115; 124) 'S::make()': (S<i32>, i64)
606 "### 606 "###
607 ); 607 );
@@ -625,10 +625,10 @@ fn test() {
625 @r###" 625 @r###"
626 [131; 203) '{ ...e(); }': () 626 [131; 203) '{ ...e(); }': ()
627 [141; 142) 'a': (S<u64>, i64) 627 [141; 142) 'a': (S<u64>, i64)
628 [158; 165) 'S::make': fn make<S<u64>, i64>() -> (Self, T) 628 [158; 165) 'S::make': fn make<S<u64>, i64>() -> (S<u64>, i64)
629 [158; 167) 'S::make()': (S<u64>, i64) 629 [158; 167) 'S::make()': (S<u64>, i64)
630 [177; 178) 'b': (S<u32>, i32) 630 [177; 178) 'b': (S<u32>, i32)
631 [191; 198) 'S::make': fn make<S<u32>, i32>() -> (Self, T) 631 [191; 198) 'S::make': fn make<S<u32>, i32>() -> (S<u32>, i32)
632 [191; 200) 'S::make()': (S<u32>, i32) 632 [191; 200) 'S::make()': (S<u32>, i32)
633 "### 633 "###
634 ); 634 );
@@ -651,10 +651,10 @@ fn test() {
651 @r###" 651 @r###"
652 [107; 211) '{ ...>(); }': () 652 [107; 211) '{ ...>(); }': ()
653 [117; 118) 'a': (S<u64>, i64, u8) 653 [117; 118) 'a': (S<u64>, i64, u8)
654 [121; 150) '<S as ...::<u8>': fn make<S<u64>, i64, u8>() -> (Self, T, U) 654 [121; 150) '<S as ...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8)
655 [121; 152) '<S as ...<u8>()': (S<u64>, i64, u8) 655 [121; 152) '<S as ...<u8>()': (S<u64>, i64, u8)
656 [162; 163) 'b': (S<u64>, i64, u8) 656 [162; 163) 'b': (S<u64>, i64, u8)
657 [182; 206) 'Trait:...::<u8>': fn make<S<u64>, i64, u8>() -> (Self, T, U) 657 [182; 206) 'Trait:...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8)
658 [182; 208) 'Trait:...<u8>()': (S<u64>, i64, u8) 658 [182; 208) 'Trait:...<u8>()': (S<u64>, i64, u8)
659 "### 659 "###
660 ); 660 );
@@ -697,7 +697,7 @@ fn test<U, T: Trait<U>>(t: T) {
697 [71; 72) 't': T 697 [71; 72) 't': T
698 [77; 96) '{ ...d(); }': () 698 [77; 96) '{ ...d(); }': ()
699 [83; 84) 't': T 699 [83; 84) 't': T
700 [83; 93) 't.method()': [missing name] 700 [83; 93) 't.method()': U
701 "### 701 "###
702 ); 702 );
703} 703}
@@ -728,7 +728,7 @@ fn test() {
728 [157; 158) 'S': S 728 [157; 158) 'S': S
729 [157; 165) 'S.into()': u64 729 [157; 165) 'S.into()': u64
730 [175; 176) 'z': u64 730 [175; 176) 'z': u64
731 [179; 196) 'Into::...::into': fn into<S, u64>(Self) -> T 731 [179; 196) 'Into::...::into': fn into<S, u64>(S) -> u64
732 [179; 199) 'Into::...nto(S)': u64 732 [179; 199) 'Into::...nto(S)': u64
733 [197; 198) 'S': S 733 [197; 198) 'S': S
734 "### 734 "###
diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs
index cb3890b42..e25d6dbc4 100644
--- a/crates/ra_hir_ty/src/tests/patterns.rs
+++ b/crates/ra_hir_ty/src/tests/patterns.rs
@@ -96,13 +96,13 @@ fn test() {
96 [38; 42) 'A(n)': A<i32> 96 [38; 42) 'A(n)': A<i32>
97 [40; 41) 'n': &i32 97 [40; 41) 'n': &i32
98 [45; 50) '&A(1)': &A<i32> 98 [45; 50) '&A(1)': &A<i32>
99 [46; 47) 'A': A<i32>(T) -> A<T> 99 [46; 47) 'A': A<i32>(i32) -> A<i32>
100 [46; 50) 'A(1)': A<i32> 100 [46; 50) 'A(1)': A<i32>
101 [48; 49) '1': i32 101 [48; 49) '1': i32
102 [60; 64) 'A(n)': A<i32> 102 [60; 64) 'A(n)': A<i32>
103 [62; 63) 'n': &mut i32 103 [62; 63) 'n': &mut i32
104 [67; 76) '&mut A(1)': &mut A<i32> 104 [67; 76) '&mut A(1)': &mut A<i32>
105 [72; 73) 'A': A<i32>(T) -> A<T> 105 [72; 73) 'A': A<i32>(i32) -> A<i32>
106 [72; 76) 'A(1)': A<i32> 106 [72; 76) 'A(1)': A<i32>
107 [74; 75) '1': i32 107 [74; 75) '1': i32
108 "### 108 "###
diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs
index 02bab6dbe..14c8ed3a9 100644
--- a/crates/ra_hir_ty/src/tests/regression.rs
+++ b/crates/ra_hir_ty/src/tests/regression.rs
@@ -346,7 +346,7 @@ pub fn main_loop() {
346 @r###" 346 @r###"
347 [144; 146) '{}': () 347 [144; 146) '{}': ()
348 [169; 198) '{ ...t(); }': () 348 [169; 198) '{ ...t(); }': ()
349 [175; 193) 'FxHash...efault': fn default<{unknown}, FxHasher>() -> HashSet<T, H> 349 [175; 193) 'FxHash...efault': fn default<{unknown}, FxHasher>() -> HashSet<{unknown}, FxHasher>
350 [175; 195) 'FxHash...ault()': HashSet<{unknown}, FxHasher> 350 [175; 195) 'FxHash...ault()': HashSet<{unknown}, FxHasher>
351 "### 351 "###
352 ); 352 );
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs
index fdab9c187..3803f5938 100644
--- a/crates/ra_hir_ty/src/tests/simple.rs
+++ b/crates/ra_hir_ty/src/tests/simple.rs
@@ -754,15 +754,15 @@ fn test() {
754 [289; 295) 'self.0': T 754 [289; 295) 'self.0': T
755 [315; 353) '{ ...))); }': () 755 [315; 353) '{ ...))); }': ()
756 [325; 326) 't': &i32 756 [325; 326) 't': &i32
757 [329; 335) 'A::foo': fn foo<i32>(&A<T>) -> &T 757 [329; 335) 'A::foo': fn foo<i32>(&A<i32>) -> &i32
758 [329; 350) 'A::foo...42))))': &i32 758 [329; 350) 'A::foo...42))))': &i32
759 [336; 349) '&&B(B(A(42)))': &&B<B<A<i32>>> 759 [336; 349) '&&B(B(A(42)))': &&B<B<A<i32>>>
760 [337; 349) '&B(B(A(42)))': &B<B<A<i32>>> 760 [337; 349) '&B(B(A(42)))': &B<B<A<i32>>>
761 [338; 339) 'B': B<B<A<i32>>>(T) -> B<T> 761 [338; 339) 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
762 [338; 349) 'B(B(A(42)))': B<B<A<i32>>> 762 [338; 349) 'B(B(A(42)))': B<B<A<i32>>>
763 [340; 341) 'B': B<A<i32>>(T) -> B<T> 763 [340; 341) 'B': B<A<i32>>(A<i32>) -> B<A<i32>>
764 [340; 348) 'B(A(42))': B<A<i32>> 764 [340; 348) 'B(A(42))': B<A<i32>>
765 [342; 343) 'A': A<i32>(T) -> A<T> 765 [342; 343) 'A': A<i32>(i32) -> A<i32>
766 [342; 347) 'A(42)': A<i32> 766 [342; 347) 'A(42)': A<i32>
767 [344; 346) '42': i32 767 [344; 346) '42': i32
768 "### 768 "###
@@ -817,16 +817,16 @@ fn test(a: A<i32>) {
817 [326; 327) 'a': A<i32> 817 [326; 327) 'a': A<i32>
818 [337; 383) '{ ...))); }': () 818 [337; 383) '{ ...))); }': ()
819 [347; 348) 't': &i32 819 [347; 348) 't': &i32
820 [351; 352) 'A': A<i32>(*mut T) -> A<T> 820 [351; 352) 'A': A<i32>(*mut i32) -> A<i32>
821 [351; 365) 'A(0 as *mut _)': A<i32> 821 [351; 365) 'A(0 as *mut _)': A<i32>
822 [351; 380) 'A(0 as...B(a)))': &i32 822 [351; 380) 'A(0 as...B(a)))': &i32
823 [353; 354) '0': i32 823 [353; 354) '0': i32
824 [353; 364) '0 as *mut _': *mut i32 824 [353; 364) '0 as *mut _': *mut i32
825 [370; 379) '&&B(B(a))': &&B<B<A<i32>>> 825 [370; 379) '&&B(B(a))': &&B<B<A<i32>>>
826 [371; 379) '&B(B(a))': &B<B<A<i32>>> 826 [371; 379) '&B(B(a))': &B<B<A<i32>>>
827 [372; 373) 'B': B<B<A<i32>>>(T) -> B<T> 827 [372; 373) 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
828 [372; 379) 'B(B(a))': B<B<A<i32>>> 828 [372; 379) 'B(B(a))': B<B<A<i32>>>
829 [374; 375) 'B': B<A<i32>>(T) -> B<T> 829 [374; 375) 'B': B<A<i32>>(A<i32>) -> B<A<i32>>
830 [374; 378) 'B(a)': B<A<i32>> 830 [374; 378) 'B(a)': B<A<i32>>
831 [376; 377) 'a': A<i32> 831 [376; 377) 'a': A<i32>
832 "### 832 "###
@@ -1169,16 +1169,16 @@ fn test() {
1169"#), 1169"#),
1170 @r###" 1170 @r###"
1171 [76; 184) '{ ...one; }': () 1171 [76; 184) '{ ...one; }': ()
1172 [82; 83) 'A': A<i32>(T) -> A<T> 1172 [82; 83) 'A': A<i32>(i32) -> A<i32>
1173 [82; 87) 'A(42)': A<i32> 1173 [82; 87) 'A(42)': A<i32>
1174 [84; 86) '42': i32 1174 [84; 86) '42': i32
1175 [93; 94) 'A': A<u128>(T) -> A<T> 1175 [93; 94) 'A': A<u128>(u128) -> A<u128>
1176 [93; 102) 'A(42u128)': A<u128> 1176 [93; 102) 'A(42u128)': A<u128>
1177 [95; 101) '42u128': u128 1177 [95; 101) '42u128': u128
1178 [108; 112) 'Some': Some<&str>(T) -> Option<T> 1178 [108; 112) 'Some': Some<&str>(&str) -> Option<&str>
1179 [108; 117) 'Some("x")': Option<&str> 1179 [108; 117) 'Some("x")': Option<&str>
1180 [113; 116) '"x"': &str 1180 [113; 116) '"x"': &str
1181 [123; 135) 'Option::Some': Some<&str>(T) -> Option<T> 1181 [123; 135) 'Option::Some': Some<&str>(&str) -> Option<&str>
1182 [123; 140) 'Option...e("x")': Option<&str> 1182 [123; 140) 'Option...e("x")': Option<&str>
1183 [136; 139) '"x"': &str 1183 [136; 139) '"x"': &str
1184 [146; 150) 'None': Option<{unknown}> 1184 [146; 150) 'None': Option<{unknown}>
@@ -1205,14 +1205,14 @@ fn test() {
1205 [21; 26) '{ t }': T 1205 [21; 26) '{ t }': T
1206 [23; 24) 't': T 1206 [23; 24) 't': T
1207 [38; 98) '{ ...(1); }': () 1207 [38; 98) '{ ...(1); }': ()
1208 [44; 46) 'id': fn id<u32>(T) -> T 1208 [44; 46) 'id': fn id<u32>(u32) -> u32
1209 [44; 52) 'id(1u32)': u32 1209 [44; 52) 'id(1u32)': u32
1210 [47; 51) '1u32': u32 1210 [47; 51) '1u32': u32
1211 [58; 68) 'id::<i128>': fn id<i128>(T) -> T 1211 [58; 68) 'id::<i128>': fn id<i128>(i128) -> i128
1212 [58; 71) 'id::<i128>(1)': i128 1212 [58; 71) 'id::<i128>(1)': i128
1213 [69; 70) '1': i128 1213 [69; 70) '1': i128
1214 [81; 82) 'x': u64 1214 [81; 82) 'x': u64
1215 [90; 92) 'id': fn id<u64>(T) -> T 1215 [90; 92) 'id': fn id<u64>(u64) -> u64
1216 [90; 95) 'id(1)': u64 1216 [90; 95) 'id(1)': u64
1217 [93; 94) '1': u64 1217 [93; 94) '1': u64
1218 "### 1218 "###
@@ -1220,7 +1220,7 @@ fn test() {
1220} 1220}
1221 1221
1222#[test] 1222#[test]
1223fn infer_impl_generics() { 1223fn infer_impl_generics_basic() {
1224 assert_snapshot!( 1224 assert_snapshot!(
1225 infer(r#" 1225 infer(r#"
1226struct A<T1, T2> { 1226struct A<T1, T2> {
@@ -1349,16 +1349,16 @@ fn test() -> i128 {
1349 [146; 147) 'x': i128 1349 [146; 147) 'x': i128
1350 [150; 151) '1': i128 1350 [150; 151) '1': i128
1351 [162; 163) 'y': i128 1351 [162; 163) 'y': i128
1352 [166; 168) 'id': fn id<i128>(T) -> T 1352 [166; 168) 'id': fn id<i128>(i128) -> i128
1353 [166; 171) 'id(x)': i128 1353 [166; 171) 'id(x)': i128
1354 [169; 170) 'x': i128 1354 [169; 170) 'x': i128
1355 [182; 183) 'a': A<i128> 1355 [182; 183) 'a': A<i128>
1356 [186; 200) 'A { x: id(y) }': A<i128> 1356 [186; 200) 'A { x: id(y) }': A<i128>
1357 [193; 195) 'id': fn id<i128>(T) -> T 1357 [193; 195) 'id': fn id<i128>(i128) -> i128
1358 [193; 198) 'id(y)': i128 1358 [193; 198) 'id(y)': i128
1359 [196; 197) 'y': i128 1359 [196; 197) 'y': i128
1360 [211; 212) 'z': i128 1360 [211; 212) 'z': i128
1361 [215; 217) 'id': fn id<i128>(T) -> T 1361 [215; 217) 'id': fn id<i128>(i128) -> i128
1362 [215; 222) 'id(a.x)': i128 1362 [215; 222) 'id(a.x)': i128
1363 [218; 219) 'a': A<i128> 1363 [218; 219) 'a': A<i128>
1364 [218; 221) 'a.x': i128 1364 [218; 221) 'a.x': i128
@@ -1502,14 +1502,14 @@ fn test() {
1502 [78; 158) '{ ...(1); }': () 1502 [78; 158) '{ ...(1); }': ()
1503 [88; 89) 'y': u32 1503 [88; 89) 'y': u32
1504 [92; 97) '10u32': u32 1504 [92; 97) '10u32': u32
1505 [103; 105) 'id': fn id<u32>(T) -> T 1505 [103; 105) 'id': fn id<u32>(u32) -> u32
1506 [103; 108) 'id(y)': u32 1506 [103; 108) 'id(y)': u32
1507 [106; 107) 'y': u32 1507 [106; 107) 'y': u32
1508 [118; 119) 'x': bool 1508 [118; 119) 'x': bool
1509 [128; 133) 'clone': fn clone<bool>(&T) -> T 1509 [128; 133) 'clone': fn clone<bool>(&bool) -> bool
1510 [128; 136) 'clone(z)': bool 1510 [128; 136) 'clone(z)': bool
1511 [134; 135) 'z': &bool 1511 [134; 135) 'z': &bool
1512 [142; 152) 'id::<i128>': fn id<i128>(T) -> T 1512 [142; 152) 'id::<i128>': fn id<i128>(i128) -> i128
1513 [142; 155) 'id::<i128>(1)': i128 1513 [142; 155) 'id::<i128>(1)': i128
1514 [153; 154) '1': i128 1514 [153; 154) '1': i128
1515 "### 1515 "###
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index a6ac18f86..17611ddbf 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -1,7 +1,6 @@
1use insta::assert_snapshot; 1use insta::assert_snapshot;
2 2
3use ra_db::fixture::WithFixture; 3use ra_db::fixture::WithFixture;
4use test_utils::covers;
5 4
6use super::{infer, infer_with_mismatches, type_at, type_at_pos}; 5use super::{infer, infer_with_mismatches, type_at, type_at_pos};
7use crate::test_db::TestDB; 6use crate::test_db::TestDB;
@@ -261,10 +260,10 @@ fn test() {
261 [92; 94) '{}': () 260 [92; 94) '{}': ()
262 [105; 144) '{ ...(s); }': () 261 [105; 144) '{ ...(s); }': ()
263 [115; 116) 's': S<u32> 262 [115; 116) 's': S<u32>
264 [119; 120) 'S': S<u32>(T) -> S<T> 263 [119; 120) 'S': S<u32>(u32) -> S<u32>
265 [119; 129) 'S(unknown)': S<u32> 264 [119; 129) 'S(unknown)': S<u32>
266 [121; 128) 'unknown': u32 265 [121; 128) 'unknown': u32
267 [135; 138) 'foo': fn foo<S<u32>>(T) -> () 266 [135; 138) 'foo': fn foo<S<u32>>(S<u32>) -> ()
268 [135; 141) 'foo(s)': () 267 [135; 141) 'foo(s)': ()
269 [139; 140) 's': S<u32> 268 [139; 140) 's': S<u32>
270 "### 269 "###
@@ -289,11 +288,11 @@ fn test() {
289 [98; 100) '{}': () 288 [98; 100) '{}': ()
290 [111; 163) '{ ...(s); }': () 289 [111; 163) '{ ...(s); }': ()
291 [121; 122) 's': S<u32> 290 [121; 122) 's': S<u32>
292 [125; 126) 'S': S<u32>(T) -> S<T> 291 [125; 126) 'S': S<u32>(u32) -> S<u32>
293 [125; 135) 'S(unknown)': S<u32> 292 [125; 135) 'S(unknown)': S<u32>
294 [127; 134) 'unknown': u32 293 [127; 134) 'unknown': u32
295 [145; 146) 'x': u32 294 [145; 146) 'x': u32
296 [154; 157) 'foo': fn foo<u32, S<u32>>(T) -> U 295 [154; 157) 'foo': fn foo<u32, S<u32>>(S<u32>) -> u32
297 [154; 160) 'foo(s)': u32 296 [154; 160) 'foo(s)': u32
298 [158; 159) 's': S<u32> 297 [158; 159) 's': S<u32>
299 "### 298 "###
@@ -358,15 +357,15 @@ fn test() {
358 [221; 223) '{}': () 357 [221; 223) '{}': ()
359 [234; 300) '{ ...(S); }': () 358 [234; 300) '{ ...(S); }': ()
360 [244; 245) 'x': u32 359 [244; 245) 'x': u32
361 [248; 252) 'foo1': fn foo1<S>(T) -> <T as Iterable>::Item 360 [248; 252) 'foo1': fn foo1<S>(S) -> <S as Iterable>::Item
362 [248; 255) 'foo1(S)': u32 361 [248; 255) 'foo1(S)': u32
363 [253; 254) 'S': S 362 [253; 254) 'S': S
364 [265; 266) 'y': u32 363 [265; 266) 'y': u32
365 [269; 273) 'foo2': fn foo2<S>(T) -> <T as Iterable>::Item 364 [269; 273) 'foo2': fn foo2<S>(S) -> <S as Iterable>::Item
366 [269; 276) 'foo2(S)': u32 365 [269; 276) 'foo2(S)': u32
367 [274; 275) 'S': S 366 [274; 275) 'S': S
368 [286; 287) 'z': u32 367 [286; 287) 'z': u32
369 [290; 294) 'foo3': fn foo3<S>(T) -> <T as Iterable>::Item 368 [290; 294) 'foo3': fn foo3<S>(S) -> <S as Iterable>::Item
370 [290; 297) 'foo3(S)': u32 369 [290; 297) 'foo3(S)': u32
371 [295; 296) 'S': S 370 [295; 296) 'S': S
372 "### 371 "###
@@ -822,8 +821,7 @@ fn test<T: ApplyL>() {
822"#, 821"#,
823 ); 822 );
824 // inside the generic function, the associated type gets normalized to a placeholder `ApplL::Out<T>` [https://rust-lang.github.io/rustc-guide/traits/associated-types.html#placeholder-associated-types]. 823 // inside the generic function, the associated type gets normalized to a placeholder `ApplL::Out<T>` [https://rust-lang.github.io/rustc-guide/traits/associated-types.html#placeholder-associated-types].
825 // FIXME: fix type parameter names going missing when going through Chalk 824 assert_eq!(t, "ApplyL::Out<T>");
826 assert_eq!(t, "ApplyL::Out<[missing name]>");
827} 825}
828 826
829#[test] 827#[test]
@@ -850,6 +848,197 @@ fn test<T: ApplyL>(t: T) {
850} 848}
851 849
852#[test] 850#[test]
851fn argument_impl_trait() {
852 assert_snapshot!(
853 infer_with_mismatches(r#"
854trait Trait<T> {
855 fn foo(&self) -> T;
856 fn foo2(&self) -> i64;
857}
858fn bar(x: impl Trait<u16>) {}
859struct S<T>(T);
860impl<T> Trait<T> for S<T> {}
861
862fn test(x: impl Trait<u64>, y: &impl Trait<u32>) {
863 x;
864 y;
865 let z = S(1);
866 bar(z);
867 x.foo();
868 y.foo();
869 z.foo();
870 x.foo2();
871 y.foo2();
872 z.foo2();
873}
874"#, true),
875 @r###"
876 [30; 34) 'self': &Self
877 [55; 59) 'self': &Self
878 [78; 79) 'x': impl Trait<u16>
879 [98; 100) '{}': ()
880 [155; 156) 'x': impl Trait<u64>
881 [175; 176) 'y': &impl Trait<u32>
882 [196; 324) '{ ...2(); }': ()
883 [202; 203) 'x': impl Trait<u64>
884 [209; 210) 'y': &impl Trait<u32>
885 [220; 221) 'z': S<u16>
886 [224; 225) 'S': S<u16>(u16) -> S<u16>
887 [224; 228) 'S(1)': S<u16>
888 [226; 227) '1': u16
889 [234; 237) 'bar': fn bar(S<u16>) -> ()
890 [234; 240) 'bar(z)': ()
891 [238; 239) 'z': S<u16>
892 [246; 247) 'x': impl Trait<u64>
893 [246; 253) 'x.foo()': u64
894 [259; 260) 'y': &impl Trait<u32>
895 [259; 266) 'y.foo()': u32
896 [272; 273) 'z': S<u16>
897 [272; 279) 'z.foo()': u16
898 [285; 286) 'x': impl Trait<u64>
899 [285; 293) 'x.foo2()': i64
900 [299; 300) 'y': &impl Trait<u32>
901 [299; 307) 'y.foo2()': i64
902 [313; 314) 'z': S<u16>
903 [313; 321) 'z.foo2()': i64
904 "###
905 );
906}
907
908#[test]
909fn argument_impl_trait_type_args_1() {
910 assert_snapshot!(
911 infer_with_mismatches(r#"
912trait Trait {}
913trait Foo {
914 // this function has an implicit Self param, an explicit type param,
915 // and an implicit impl Trait param!
916 fn bar<T>(x: impl Trait) -> T { loop {} }
917}
918fn foo<T>(x: impl Trait) -> T { loop {} }
919struct S;
920impl Trait for S {}
921struct F;
922impl Foo for F {}
923
924fn test() {
925 Foo::bar(S);
926 <F as Foo>::bar(S);
927 F::bar(S);
928 Foo::bar::<u32>(S);
929 <F as Foo>::bar::<u32>(S);
930
931 foo(S);
932 foo::<u32>(S);
933 foo::<u32, i32>(S); // we should ignore the extraneous i32
934}
935"#, true),
936 @r###"
937 [156; 157) 'x': impl Trait
938 [176; 187) '{ loop {} }': T
939 [178; 185) 'loop {}': !
940 [183; 185) '{}': ()
941 [200; 201) 'x': impl Trait
942 [220; 231) '{ loop {} }': T
943 [222; 229) 'loop {}': !
944 [227; 229) '{}': ()
945 [301; 510) '{ ... i32 }': ()
946 [307; 315) 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown}
947 [307; 318) 'Foo::bar(S)': {unknown}
948 [316; 317) 'S': S
949 [324; 339) '<F as Foo>::bar': fn bar<F, {unknown}>(S) -> {unknown}
950 [324; 342) '<F as ...bar(S)': {unknown}
951 [340; 341) 'S': S
952 [348; 354) 'F::bar': fn bar<F, {unknown}>(S) -> {unknown}
953 [348; 357) 'F::bar(S)': {unknown}
954 [355; 356) 'S': S
955 [363; 378) 'Foo::bar::<u32>': fn bar<{unknown}, u32>(S) -> u32
956 [363; 381) 'Foo::b...32>(S)': u32
957 [379; 380) 'S': S
958 [387; 409) '<F as ...:<u32>': fn bar<F, u32>(S) -> u32
959 [387; 412) '<F as ...32>(S)': u32
960 [410; 411) 'S': S
961 [419; 422) 'foo': fn foo<{unknown}>(S) -> {unknown}
962 [419; 425) 'foo(S)': {unknown}
963 [423; 424) 'S': S
964 [431; 441) 'foo::<u32>': fn foo<u32>(S) -> u32
965 [431; 444) 'foo::<u32>(S)': u32
966 [442; 443) 'S': S
967 [450; 465) 'foo::<u32, i32>': fn foo<u32>(S) -> u32
968 [450; 468) 'foo::<...32>(S)': u32
969 [466; 467) 'S': S
970 "###
971 );
972}
973
974#[test]
975fn argument_impl_trait_type_args_2() {
976 assert_snapshot!(
977 infer_with_mismatches(r#"
978trait Trait {}
979struct S;
980impl Trait for S {}
981struct F<T>;
982impl<T> F<T> {
983 fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} }
984}
985
986fn test() {
987 F.foo(S);
988 F::<u32>.foo(S);
989 F::<u32>.foo::<i32>(S);
990 F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored
991}
992"#, true),
993 @r###"
994 [88; 92) 'self': F<T>
995 [94; 95) 'x': impl Trait
996 [119; 130) '{ loop {} }': (T, U)
997 [121; 128) 'loop {}': !
998 [126; 128) '{}': ()
999 [144; 284) '{ ...ored }': ()
1000 [150; 151) 'F': F<{unknown}>
1001 [150; 158) 'F.foo(S)': ({unknown}, {unknown})
1002 [156; 157) 'S': S
1003 [164; 172) 'F::<u32>': F<u32>
1004 [164; 179) 'F::<u32>.foo(S)': (u32, {unknown})
1005 [177; 178) 'S': S
1006 [185; 193) 'F::<u32>': F<u32>
1007 [185; 207) 'F::<u3...32>(S)': (u32, i32)
1008 [205; 206) 'S': S
1009 [213; 221) 'F::<u32>': F<u32>
1010 [213; 240) 'F::<u3...32>(S)': (u32, i32)
1011 [238; 239) 'S': S
1012 "###
1013 );
1014}
1015
1016#[test]
1017fn argument_impl_trait_to_fn_pointer() {
1018 assert_snapshot!(
1019 infer_with_mismatches(r#"
1020trait Trait {}
1021fn foo(x: impl Trait) { loop {} }
1022struct S;
1023impl Trait for S {}
1024
1025fn test() {
1026 let f: fn(S) -> () = foo;
1027}
1028"#, true),
1029 @r###"
1030 [23; 24) 'x': impl Trait
1031 [38; 49) '{ loop {} }': ()
1032 [40; 47) 'loop {}': !
1033 [45; 47) '{}': ()
1034 [91; 124) '{ ...foo; }': ()
1035 [101; 102) 'f': fn(S) -> ()
1036 [118; 121) 'foo': fn foo(S) -> ()
1037 "###
1038 );
1039}
1040
1041#[test]
853#[ignore] 1042#[ignore]
854fn impl_trait() { 1043fn impl_trait() {
855 assert_snapshot!( 1044 assert_snapshot!(
@@ -994,29 +1183,17 @@ fn weird_bounds() {
994 assert_snapshot!( 1183 assert_snapshot!(
995 infer(r#" 1184 infer(r#"
996trait Trait {} 1185trait Trait {}
997fn test() { 1186fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) {
998 let a: impl Trait + 'lifetime = foo;
999 let b: impl 'lifetime = foo;
1000 let b: impl (Trait) = foo;
1001 let b: impl ('lifetime) = foo;
1002 let d: impl ?Sized = foo;
1003 let e: impl Trait + ?Sized = foo;
1004} 1187}
1005"#), 1188"#),
1006 @r###" 1189 @r###"
1007 [26; 237) '{ ...foo; }': () 1190 [24; 25) 'a': impl Trait + {error}
1008 [36; 37) 'a': impl Trait + {error} 1191 [51; 52) 'b': impl {error}
1009 [64; 67) 'foo': impl Trait + {error} 1192 [70; 71) 'c': impl Trait
1010 [77; 78) 'b': impl {error} 1193 [87; 88) 'd': impl {error}
1011 [97; 100) 'foo': impl {error} 1194 [108; 109) 'e': impl {error}
1012 [110; 111) 'b': impl Trait 1195 [124; 125) 'f': impl Trait + {error}
1013 [128; 131) 'foo': impl Trait 1196 [148; 151) '{ }': ()
1014 [141; 142) 'b': impl {error}
1015 [163; 166) 'foo': impl {error}
1016 [176; 177) 'd': impl {error}
1017 [193; 196) 'foo': impl {error}
1018 [206; 207) 'e': impl Trait + {error}
1019 [231; 234) 'foo': impl Trait + {error}
1020 "### 1197 "###
1021 ); 1198 );
1022} 1199}
@@ -1078,26 +1255,26 @@ fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
1078 [296; 299) 'get': fn get<T>(T) -> <T as Trait>::Type 1255 [296; 299) 'get': fn get<T>(T) -> <T as Trait>::Type
1079 [296; 302) 'get(x)': {unknown} 1256 [296; 302) 'get(x)': {unknown}
1080 [300; 301) 'x': T 1257 [300; 301) 'x': T
1081 [308; 312) 'get2': fn get2<{unknown}, T>(T) -> U 1258 [308; 312) 'get2': fn get2<{unknown}, T>(T) -> {unknown}
1082 [308; 315) 'get2(x)': {unknown} 1259 [308; 315) 'get2(x)': {unknown}
1083 [313; 314) 'x': T 1260 [313; 314) 'x': T
1084 [321; 324) 'get': fn get<impl Trait<Type = i64>>(T) -> <T as Trait>::Type 1261 [321; 324) 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type
1085 [321; 327) 'get(y)': {unknown} 1262 [321; 327) 'get(y)': {unknown}
1086 [325; 326) 'y': impl Trait<Type = i64> 1263 [325; 326) 'y': impl Trait<Type = i64>
1087 [333; 337) 'get2': fn get2<{unknown}, impl Trait<Type = i64>>(T) -> U 1264 [333; 337) 'get2': fn get2<{unknown}, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> {unknown}
1088 [333; 340) 'get2(y)': {unknown} 1265 [333; 340) 'get2(y)': {unknown}
1089 [338; 339) 'y': impl Trait<Type = i64> 1266 [338; 339) 'y': impl Trait<Type = i64>
1090 [346; 349) 'get': fn get<S<u64>>(T) -> <T as Trait>::Type 1267 [346; 349) 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type
1091 [346; 357) 'get(set(S))': u64 1268 [346; 357) 'get(set(S))': u64
1092 [350; 353) 'set': fn set<S<u64>>(T) -> T 1269 [350; 353) 'set': fn set<S<u64>>(S<u64>) -> S<u64>
1093 [350; 356) 'set(S)': S<u64> 1270 [350; 356) 'set(S)': S<u64>
1094 [354; 355) 'S': S<u64> 1271 [354; 355) 'S': S<u64>
1095 [363; 367) 'get2': fn get2<u64, S<u64>>(T) -> U 1272 [363; 367) 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64
1096 [363; 375) 'get2(set(S))': u64 1273 [363; 375) 'get2(set(S))': u64
1097 [368; 371) 'set': fn set<S<u64>>(T) -> T 1274 [368; 371) 'set': fn set<S<u64>>(S<u64>) -> S<u64>
1098 [368; 374) 'set(S)': S<u64> 1275 [368; 374) 'set(S)': S<u64>
1099 [372; 373) 'S': S<u64> 1276 [372; 373) 'S': S<u64>
1100 [381; 385) 'get2': fn get2<str, S<str>>(T) -> U 1277 [381; 385) 'get2': fn get2<str, S<str>>(S<str>) -> str
1101 [381; 395) 'get2(S::<str>)': str 1278 [381; 395) 'get2(S::<str>)': str
1102 [386; 394) 'S::<str>': S<str> 1279 [386; 394) 'S::<str>': S<str>
1103 "### 1280 "###
@@ -1225,6 +1402,32 @@ fn test<T: Trait1, U: Trait2>(x: T, y: U) {
1225} 1402}
1226 1403
1227#[test] 1404#[test]
1405fn super_trait_impl_trait_method_resolution() {
1406 assert_snapshot!(
1407 infer(r#"
1408mod foo {
1409 trait SuperTrait {
1410 fn foo(&self) -> u32 {}
1411 }
1412}
1413trait Trait1: foo::SuperTrait {}
1414
1415fn test(x: &impl Trait1) {
1416 x.foo();
1417}
1418"#),
1419 @r###"
1420 [50; 54) 'self': &Self
1421 [63; 65) '{}': ()
1422 [116; 117) 'x': &impl Trait1
1423 [133; 149) '{ ...o(); }': ()
1424 [139; 140) 'x': &impl Trait1
1425 [139; 146) 'x.foo()': u32
1426 "###
1427 );
1428}
1429
1430#[test]
1228fn super_trait_cycle() { 1431fn super_trait_cycle() {
1229 // This just needs to not crash 1432 // This just needs to not crash
1230 assert_snapshot!( 1433 assert_snapshot!(
@@ -1270,9 +1473,9 @@ fn test() {
1270 [157; 160) '{t}': T 1473 [157; 160) '{t}': T
1271 [158; 159) 't': T 1474 [158; 159) 't': T
1272 [259; 280) '{ ...S)); }': () 1475 [259; 280) '{ ...S)); }': ()
1273 [265; 269) 'get2': fn get2<u64, S<u64>>(T) -> U 1476 [265; 269) 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64
1274 [265; 277) 'get2(set(S))': u64 1477 [265; 277) 'get2(set(S))': u64
1275 [270; 273) 'set': fn set<S<u64>>(T) -> T 1478 [270; 273) 'set': fn set<S<u64>>(S<u64>) -> S<u64>
1276 [270; 276) 'set(S)': S<u64> 1479 [270; 276) 'set(S)': S<u64>
1277 [274; 275) 'S': S<u64> 1480 [274; 275) 'S': S<u64>
1278 "### 1481 "###
@@ -1334,7 +1537,7 @@ fn test() {
1334 [173; 175) '{}': () 1537 [173; 175) '{}': ()
1335 [189; 308) '{ ... 1); }': () 1538 [189; 308) '{ ... 1); }': ()
1336 [199; 200) 'x': Option<u32> 1539 [199; 200) 'x': Option<u32>
1337 [203; 215) 'Option::Some': Some<u32>(T) -> Option<T> 1540 [203; 215) 'Option::Some': Some<u32>(u32) -> Option<u32>
1338 [203; 221) 'Option...(1u32)': Option<u32> 1541 [203; 221) 'Option...(1u32)': Option<u32>
1339 [216; 220) '1u32': u32 1542 [216; 220) '1u32': u32
1340 [227; 228) 'x': Option<u32> 1543 [227; 228) 'x': Option<u32>
@@ -1444,7 +1647,7 @@ fn test() {
1444 [340; 342) '{}': () 1647 [340; 342) '{}': ()
1445 [356; 515) '{ ... S); }': () 1648 [356; 515) '{ ... S); }': ()
1446 [366; 368) 'x1': u64 1649 [366; 368) 'x1': u64
1447 [371; 375) 'foo1': fn foo1<S, u64, |S| -> u64>(T, F) -> U 1650 [371; 375) 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64
1448 [371; 394) 'foo1(S...hod())': u64 1651 [371; 394) 'foo1(S...hod())': u64
1449 [376; 377) 'S': S 1652 [376; 377) 'S': S
1450 [379; 393) '|s| s.method()': |S| -> u64 1653 [379; 393) '|s| s.method()': |S| -> u64
@@ -1452,7 +1655,7 @@ fn test() {
1452 [383; 384) 's': S 1655 [383; 384) 's': S
1453 [383; 393) 's.method()': u64 1656 [383; 393) 's.method()': u64
1454 [404; 406) 'x2': u64 1657 [404; 406) 'x2': u64
1455 [409; 413) 'foo2': fn foo2<S, u64, |S| -> u64>(F, T) -> U 1658 [409; 413) 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64
1456 [409; 432) 'foo2(|...(), S)': u64 1659 [409; 432) 'foo2(|...(), S)': u64
1457 [414; 428) '|s| s.method()': |S| -> u64 1660 [414; 428) '|s| s.method()': |S| -> u64
1458 [415; 416) 's': S 1661 [415; 416) 's': S
@@ -1605,7 +1808,6 @@ fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> {
1605 1808
1606#[test] 1809#[test]
1607fn unify_impl_trait() { 1810fn unify_impl_trait() {
1608 covers!(insert_vars_for_impl_trait);
1609 assert_snapshot!( 1811 assert_snapshot!(
1610 infer_with_mismatches(r#" 1812 infer_with_mismatches(r#"
1611trait Trait<T> {} 1813trait Trait<T> {}
@@ -1637,26 +1839,26 @@ fn test() -> impl Trait<i32> {
1637 [172; 183) '{ loop {} }': T 1839 [172; 183) '{ loop {} }': T
1638 [174; 181) 'loop {}': ! 1840 [174; 181) 'loop {}': !
1639 [179; 181) '{}': () 1841 [179; 181) '{}': ()
1640 [214; 310) '{ ...t()) }': S<i32> 1842 [214; 310) '{ ...t()) }': S<{unknown}>
1641 [224; 226) 's1': S<u32> 1843 [224; 226) 's1': S<u32>
1642 [229; 230) 'S': S<u32>(T) -> S<T> 1844 [229; 230) 'S': S<u32>(u32) -> S<u32>
1643 [229; 241) 'S(default())': S<u32> 1845 [229; 241) 'S(default())': S<u32>
1644 [231; 238) 'default': fn default<u32>() -> T 1846 [231; 238) 'default': fn default<u32>() -> u32
1645 [231; 240) 'default()': u32 1847 [231; 240) 'default()': u32
1646 [247; 250) 'foo': fn foo(impl Trait<u32>) -> () 1848 [247; 250) 'foo': fn foo(S<u32>) -> ()
1647 [247; 254) 'foo(s1)': () 1849 [247; 254) 'foo(s1)': ()
1648 [251; 253) 's1': S<u32> 1850 [251; 253) 's1': S<u32>
1649 [264; 265) 'x': i32 1851 [264; 265) 'x': i32
1650 [273; 276) 'bar': fn bar<i32>(impl Trait<T>) -> T 1852 [273; 276) 'bar': fn bar<i32>(S<i32>) -> i32
1651 [273; 290) 'bar(S(...lt()))': i32 1853 [273; 290) 'bar(S(...lt()))': i32
1652 [277; 278) 'S': S<i32>(T) -> S<T> 1854 [277; 278) 'S': S<i32>(i32) -> S<i32>
1653 [277; 289) 'S(default())': S<i32> 1855 [277; 289) 'S(default())': S<i32>
1654 [279; 286) 'default': fn default<i32>() -> T 1856 [279; 286) 'default': fn default<i32>() -> i32
1655 [279; 288) 'default()': i32 1857 [279; 288) 'default()': i32
1656 [296; 297) 'S': S<i32>(T) -> S<T> 1858 [296; 297) 'S': S<{unknown}>({unknown}) -> S<{unknown}>
1657 [296; 308) 'S(default())': S<i32> 1859 [296; 308) 'S(default())': S<{unknown}>
1658 [298; 305) 'default': fn default<i32>() -> T 1860 [298; 305) 'default': fn default<{unknown}>() -> {unknown}
1659 [298; 307) 'default()': i32 1861 [298; 307) 'default()': {unknown}
1660 "### 1862 "###
1661 ); 1863 );
1662} 1864}
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index fe9cb556c..4974c565b 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -14,7 +14,7 @@ use ra_db::{
14use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; 14use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
15use crate::{ 15use crate::{
16 db::HirDatabase, display::HirDisplay, utils::generics, ApplicationTy, GenericPredicate, 16 db::HirDatabase, display::HirDisplay, utils::generics, ApplicationTy, GenericPredicate,
17 ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, 17 ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
18}; 18};
19 19
20#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] 20#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
@@ -142,9 +142,13 @@ impl ToChalk for Ty {
142 let substitution = proj_ty.parameters.to_chalk(db); 142 let substitution = proj_ty.parameters.to_chalk(db);
143 chalk_ir::AliasTy { associated_ty_id, substitution }.cast().intern() 143 chalk_ir::AliasTy { associated_ty_id, substitution }.cast().intern()
144 } 144 }
145 Ty::Param { idx, .. } => { 145 Ty::Param(id) => {
146 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize } 146 let interned_id = db.intern_type_param_id(id);
147 .to_ty::<TypeFamily>() 147 PlaceholderIndex {
148 ui: UniverseIndex::ROOT,
149 idx: interned_id.as_intern_id().as_usize(),
150 }
151 .to_ty::<TypeFamily>()
148 } 152 }
149 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(), 153 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(),
150 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 154 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
@@ -177,7 +181,10 @@ impl ToChalk for Ty {
177 }, 181 },
178 chalk_ir::TyData::Placeholder(idx) => { 182 chalk_ir::TyData::Placeholder(idx) => {
179 assert_eq!(idx.ui, UniverseIndex::ROOT); 183 assert_eq!(idx.ui, UniverseIndex::ROOT);
180 Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() } 184 let interned_id = crate::db::GlobalTypeParamId::from_intern_id(
185 crate::salsa::InternId::from(idx.idx),
186 );
187 Ty::Param(db.lookup_intern_type_param_id(interned_id))
181 } 188 }
182 chalk_ir::TyData::Alias(proj) => { 189 chalk_ir::TyData::Alias(proj) => {
183 let associated_ty = from_chalk(db, proj.associated_ty_id); 190 let associated_ty = from_chalk(db, proj.associated_ty_id);
@@ -520,7 +527,7 @@ fn convert_where_clauses(
520 let generic_predicates = db.generic_predicates(def); 527 let generic_predicates = db.generic_predicates(def);
521 let mut result = Vec::with_capacity(generic_predicates.len()); 528 let mut result = Vec::with_capacity(generic_predicates.len());
522 for pred in generic_predicates.iter() { 529 for pred in generic_predicates.iter() {
523 if pred.is_error() { 530 if pred.value.is_error() {
524 // skip errored predicates completely 531 // skip errored predicates completely
525 continue; 532 continue;
526 } 533 }
@@ -709,12 +716,12 @@ fn impl_block_datum(
709 let trait_ref = db 716 let trait_ref = db
710 .impl_trait(impl_id) 717 .impl_trait(impl_id)
711 // ImplIds for impls where the trait ref can't be resolved should never reach Chalk 718 // ImplIds for impls where the trait ref can't be resolved should never reach Chalk
712 .expect("invalid impl passed to Chalk"); 719 .expect("invalid impl passed to Chalk")
720 .value;
713 let impl_data = db.impl_data(impl_id); 721 let impl_data = db.impl_data(impl_id);
714 722
715 let generic_params = generics(db, impl_id.into()); 723 let generic_params = generics(db, impl_id.into());
716 let bound_vars = Substs::bound_vars(&generic_params); 724 let bound_vars = Substs::bound_vars(&generic_params);
717 let trait_ref = trait_ref.subst(&bound_vars);
718 let trait_ = trait_ref.trait_; 725 let trait_ = trait_ref.trait_;
719 let impl_type = if impl_id.lookup(db).container.module(db).krate == krate { 726 let impl_type = if impl_id.lookup(db).container.module(db).krate == krate {
720 chalk_rust_ir::ImplType::Local 727 chalk_rust_ir::ImplType::Local
@@ -789,20 +796,18 @@ fn type_alias_associated_ty_value(
789 _ => panic!("assoc ty value should be in impl"), 796 _ => panic!("assoc ty value should be in impl"),
790 }; 797 };
791 798
792 let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist"); // we don't return any assoc ty values if the impl'd trait can't be resolved 799 let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved
793 800
794 let assoc_ty = db 801 let assoc_ty = db
795 .trait_data(trait_ref.trait_) 802 .trait_data(trait_ref.trait_)
796 .associated_type_by_name(&type_alias_data.name) 803 .associated_type_by_name(&type_alias_data.name)
797 .expect("assoc ty value should not exist"); // validated when building the impl data as well 804 .expect("assoc ty value should not exist"); // validated when building the impl data as well
798 let generic_params = generics(db, impl_id.into()); 805 let ty = db.ty(type_alias.into());
799 let bound_vars = Substs::bound_vars(&generic_params); 806 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) };
800 let ty = db.ty(type_alias.into()).subst(&bound_vars);
801 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) };
802 let value = chalk_rust_ir::AssociatedTyValue { 807 let value = chalk_rust_ir::AssociatedTyValue {
803 impl_id: Impl::ImplBlock(impl_id.into()).to_chalk(db), 808 impl_id: Impl::ImplBlock(impl_id.into()).to_chalk(db),
804 associated_ty_id: assoc_ty.to_chalk(db), 809 associated_ty_id: assoc_ty.to_chalk(db),
805 value: make_binders(value_bound, bound_vars.len()), 810 value: make_binders(value_bound, ty.num_binders),
806 }; 811 };
807 Arc::new(value) 812 Arc::new(value)
808} 813}
diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs
index 0b1806a84..508ae9046 100644
--- a/crates/ra_hir_ty/src/utils.rs
+++ b/crates/ra_hir_ty/src/utils.rs
@@ -2,10 +2,11 @@
2//! query, but can't be computed directly from `*Data` (ie, which need a `db`). 2//! query, but can't be computed directly from `*Data` (ie, which need a `db`).
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::generics::WherePredicateTarget;
5use hir_def::{ 6use hir_def::{
6 adt::VariantData, 7 adt::VariantData,
7 db::DefDatabase, 8 db::DefDatabase,
8 generics::{GenericParams, TypeParamData}, 9 generics::{GenericParams, TypeParamData, TypeParamProvenance},
9 path::Path, 10 path::Path,
10 resolver::{HasResolver, TypeNs}, 11 resolver::{HasResolver, TypeNs},
11 type_ref::TypeRef, 12 type_ref::TypeRef,
@@ -19,11 +20,18 @@ fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec<TraitId> {
19 // lifetime problems, but since there usually shouldn't be more than a 20 // lifetime problems, but since there usually shouldn't be more than a
20 // few direct traits this should be fine (we could even use some kind of 21 // few direct traits this should be fine (we could even use some kind of
21 // SmallVec if performance is a concern) 22 // SmallVec if performance is a concern)
22 db.generic_params(trait_.into()) 23 let generic_params = db.generic_params(trait_.into());
24 let trait_self = generic_params.find_trait_self_param();
25 generic_params
23 .where_predicates 26 .where_predicates
24 .iter() 27 .iter()
25 .filter_map(|pred| match &pred.type_ref { 28 .filter_map(|pred| match &pred.target {
26 TypeRef::Path(p) if p == &Path::from(name![Self]) => pred.bound.as_path(), 29 WherePredicateTarget::TypeRef(TypeRef::Path(p)) if p == &Path::from(name![Self]) => {
30 pred.bound.as_path()
31 }
32 WherePredicateTarget::TypeParam(local_id) if Some(*local_id) == trait_self => {
33 pred.bound.as_path()
34 }
27 _ => None, 35 _ => None,
28 }) 36 })
29 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) { 37 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) {
@@ -95,41 +103,77 @@ pub(crate) struct Generics {
95} 103}
96 104
97impl Generics { 105impl Generics {
98 pub(crate) fn iter<'a>(&'a self) -> impl Iterator<Item = (u32, &'a TypeParamData)> + 'a { 106 pub(crate) fn iter<'a>(
107 &'a self,
108 ) -> impl Iterator<Item = (TypeParamId, &'a TypeParamData)> + 'a {
99 self.parent_generics 109 self.parent_generics
100 .as_ref() 110 .as_ref()
101 .into_iter() 111 .into_iter()
102 .flat_map(|it| it.params.types.iter()) 112 .flat_map(|it| {
103 .chain(self.params.types.iter()) 113 it.params
104 .enumerate() 114 .types
105 .map(|(i, (_local_id, p))| (i as u32, p)) 115 .iter()
116 .map(move |(local_id, p)| (TypeParamId { parent: it.def, local_id }, p))
117 })
118 .chain(
119 self.params
120 .types
121 .iter()
122 .map(move |(local_id, p)| (TypeParamId { parent: self.def, local_id }, p)),
123 )
106 } 124 }
107 125
108 pub(crate) fn iter_parent<'a>(&'a self) -> impl Iterator<Item = (u32, &'a TypeParamData)> + 'a { 126 pub(crate) fn iter_parent<'a>(
109 self.parent_generics 127 &'a self,
110 .as_ref() 128 ) -> impl Iterator<Item = (TypeParamId, &'a TypeParamData)> + 'a {
111 .into_iter() 129 self.parent_generics.as_ref().into_iter().flat_map(|it| {
112 .flat_map(|it| it.params.types.iter()) 130 it.params
113 .enumerate() 131 .types
114 .map(|(i, (_local_id, p))| (i as u32, p)) 132 .iter()
133 .map(move |(local_id, p)| (TypeParamId { parent: it.def, local_id }, p))
134 })
115 } 135 }
116 136
117 pub(crate) fn len(&self) -> usize { 137 pub(crate) fn len(&self) -> usize {
118 self.len_split().0 138 self.len_split().0
119 } 139 }
140
120 /// (total, parents, child) 141 /// (total, parents, child)
121 pub(crate) fn len_split(&self) -> (usize, usize, usize) { 142 pub(crate) fn len_split(&self) -> (usize, usize, usize) {
122 let parent = self.parent_generics.as_ref().map_or(0, |p| p.len()); 143 let parent = self.parent_generics.as_ref().map_or(0, |p| p.len());
123 let child = self.params.types.len(); 144 let child = self.params.types.len();
124 (parent + child, parent, child) 145 (parent + child, parent, child)
125 } 146 }
126 pub(crate) fn param_idx(&self, param: TypeParamId) -> u32 { 147
127 self.find_param(param).0 148 /// (parent total, self param, type param list, impl trait)
149 pub(crate) fn provenance_split(&self) -> (usize, usize, usize, usize) {
150 let parent = self.parent_generics.as_ref().map_or(0, |p| p.len());
151 let self_params = self
152 .params
153 .types
154 .iter()
155 .filter(|(_, p)| p.provenance == TypeParamProvenance::TraitSelf)
156 .count();
157 let list_params = self
158 .params
159 .types
160 .iter()
161 .filter(|(_, p)| p.provenance == TypeParamProvenance::TypeParamList)
162 .count();
163 let impl_trait_params = self
164 .params
165 .types
166 .iter()
167 .filter(|(_, p)| p.provenance == TypeParamProvenance::ArgumentImplTrait)
168 .count();
169 (parent, self_params, list_params, impl_trait_params)
128 } 170 }
129 pub(crate) fn param_name(&self, param: TypeParamId) -> Name { 171
130 self.find_param(param).1.name.clone() 172 pub(crate) fn param_idx(&self, param: TypeParamId) -> Option<u32> {
173 Some(self.find_param(param)?.0)
131 } 174 }
132 fn find_param(&self, param: TypeParamId) -> (u32, &TypeParamData) { 175
176 fn find_param(&self, param: TypeParamId) -> Option<(u32, &TypeParamData)> {
133 if param.parent == self.def { 177 if param.parent == self.def {
134 let (idx, (_local_id, data)) = self 178 let (idx, (_local_id, data)) = self
135 .params 179 .params
@@ -139,9 +183,10 @@ impl Generics {
139 .find(|(_, (idx, _))| *idx == param.local_id) 183 .find(|(_, (idx, _))| *idx == param.local_id)
140 .unwrap(); 184 .unwrap();
141 let (_total, parent_len, _child) = self.len_split(); 185 let (_total, parent_len, _child) = self.len_split();
142 return ((parent_len + idx) as u32, data); 186 Some(((parent_len + idx) as u32, data))
187 } else {
188 self.parent_generics.as_ref().and_then(|g| g.find_param(param))
143 } 189 }
144 self.parent_generics.as_ref().unwrap().find_param(param)
145 } 190 }
146} 191}
147 192