diff options
Diffstat (limited to 'crates')
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 @@ | |||
1 | use format_buf::format; | 1 | use format_buf::format; |
2 | use hir::InFile; | 2 | use hir::{Adt, InFile}; |
3 | use join_to_string::join; | 3 | use join_to_string::join; |
4 | use ra_syntax::{ | 4 | use 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 | }; |
17 | use hir_expand::{ | 17 | use hir_expand::{ |
18 | diagnostics::DiagnosticSink, | 18 | diagnostics::DiagnosticSink, |
@@ -21,7 +21,7 @@ use hir_expand::{ | |||
21 | }; | 21 | }; |
22 | use hir_ty::{ | 22 | use 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 | }; |
26 | use ra_db::{CrateId, Edition, FileId}; | 26 | use ra_db::{CrateId, Edition, FileId}; |
27 | use ra_prof::profile; | 27 | use 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 { | |||
755 | impl TypeParam { | 761 | impl 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)] |
29 | pub struct TypeParamData { | 29 | pub 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)] | ||
36 | pub 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)] |
47 | pub struct WherePredicate { | 55 | pub 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)] | ||
61 | pub enum WherePredicateTarget { | ||
62 | TypeRef(TypeRef), | ||
63 | /// For desugared where predicates that can directly refer to a type param. | ||
64 | TypeParam(LocalTypeParamId), | ||
65 | } | ||
66 | |||
52 | type SourceMap = ArenaMap<LocalTypeParamId, Either<ast::TraitDef, ast::TypeParam>>; | 67 | type SourceMap = ArenaMap<LocalTypeParamId, Either<ast::TraitDef, ast::TypeParam>>; |
53 | 68 | ||
54 | impl GenericParams { | 69 | impl 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) = ¶m.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 | ||
129 | pub(crate) fn type_bounds_from_ast(type_bounds_opt: Option<ast::TypeBoundList>) -> Vec<TypeBound> { | 171 | pub(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 @@ | |||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::{ | 5 | use hir_def::{ |
6 | db::DefDatabase, DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId, | 6 | db::DefDatabase, DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, TypeParamId, |
7 | VariantId, | ||
7 | }; | 8 | }; |
8 | use ra_arena::map::ArenaMap; | 9 | use ra_arena::map::ArenaMap; |
9 | use ra_db::{salsa, CrateId}; | 10 | use ra_db::{impl_intern_key, salsa, CrateId}; |
10 | use ra_prof::profile; | 11 | use ra_prof::profile; |
11 | 12 | ||
12 | use crate::{ | 13 | use 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> { | |||
117 | fn hir_database_is_object_safe() { | 119 | fn 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)] | ||
124 | pub struct GlobalTypeParamId(salsa::InternId); | ||
125 | impl_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}; | |||
34 | use ra_arena::map::ArenaMap; | 34 | use ra_arena::map::ArenaMap; |
35 | use ra_prof::profile; | 35 | use ra_prof::profile; |
36 | use ra_syntax::SmolStr; | 36 | use ra_syntax::SmolStr; |
37 | use test_utils::tested_by; | ||
38 | 37 | ||
39 | use super::{ | 38 | use 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 | }; |
45 | use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic}; | 44 | use crate::{ |
45 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, | ||
46 | }; | ||
46 | 47 | ||
47 | pub(crate) use unify::unify; | 48 | pub(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 | }; |
13 | use hir_expand::name::{name, Name}; | 13 | use hir_expand::name::Name; |
14 | use ra_syntax::ast::RangeOp; | 14 | use ra_syntax::ast::RangeOp; |
15 | 15 | ||
16 | use crate::{ | 16 | use 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 | ||
26 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; | 26 | use 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; | |||
12 | use test_utils::tested_by; | 12 | use test_utils::tested_by; |
13 | 13 | ||
14 | use super::{BindingMode, InferenceContext}; | 14 | use super::{BindingMode, InferenceContext}; |
15 | use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor, TypeWalk}; | 15 | use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor}; |
16 | 16 | ||
17 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 17 | impl<'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 | }; |
10 | use hir_expand::name::Name; | 10 | use hir_expand::name::Name; |
11 | 11 | ||
12 | use crate::{db::HirDatabase, method_resolution, Substs, Ty, TypeWalk, ValueTyDefId}; | 12 | use crate::{db::HirDatabase, method_resolution, Substs, Ty, ValueTyDefId}; |
13 | 13 | ||
14 | use super::{ExprOrPatId, InferenceContext, TraitEnvironment, TraitRef}; | 14 | use super::{ExprOrPatId, InferenceContext, TraitRef}; |
15 | 15 | ||
16 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 16 | impl<'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; | |||
44 | use std::{fmt, iter, mem}; | 44 | use std::{fmt, iter, mem}; |
45 | 45 | ||
46 | use hir_def::{ | 46 | use 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 | }; |
50 | use hir_expand::name::Name; | 50 | use hir_expand::name::Name; |
51 | use ra_db::{impl_intern_key, salsa, CrateId}; | 51 | use ra_db::{impl_intern_key, salsa, CrateId}; |
@@ -60,7 +60,9 @@ use display::{HirDisplay, HirFormatter}; | |||
60 | pub use autoderef::autoderef; | 60 | pub use autoderef::autoderef; |
61 | pub use infer::{do_infer_query, InferTy, InferenceResult}; | 61 | pub use infer::{do_infer_query, InferTy, InferenceResult}; |
62 | pub use lower::CallableDef; | 62 | pub use lower::CallableDef; |
63 | pub use lower::{callable_item_sig, TyDefId, ValueTyDefId}; | 63 | pub use lower::{ |
64 | callable_item_sig, ImplTraitLoweringMode, TyDefId, TyLoweringContext, ValueTyDefId, | ||
65 | }; | ||
64 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; | 66 | pub 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(¶ms) | ||
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)] | ||
454 | pub struct Binders<T> { | ||
455 | pub num_binders: usize, | ||
456 | pub value: T, | ||
457 | } | ||
458 | |||
459 | impl<T> Binders<T> { | ||
460 | pub fn new(num_binders: usize, value: T) -> Self { | ||
461 | Self { num_binders, value } | ||
462 | } | ||
463 | } | ||
464 | |||
465 | impl<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. | ||
580 | pub type PolyFnSig = Binders<FnSig>; | ||
581 | |||
554 | impl FnSig { | 582 | impl 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 | ||
1069 | fn 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 | |||
1088 | impl TraitRef { | 1134 | impl 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 | ||
11 | use hir_def::{ | 11 | use 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 | }; |
20 | use ra_arena::map::ArenaMap; | 21 | use ra_arena::map::ArenaMap; |
21 | use ra_db::CrateId; | 22 | use 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)] | ||
36 | pub 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 | |||
48 | impl<'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)] | ||
66 | pub 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)] | ||
86 | pub enum TypeParamLoweringMode { | ||
87 | Placeholder, | ||
88 | Variable, | ||
89 | } | ||
90 | |||
34 | impl Ty { | 91 | impl 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 | ||
312 | pub(super) fn substs_from_path_segment( | 423 | pub(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 | ||
366 | impl TraitRef { | 474 | impl 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 | ||
432 | impl GenericPredicate { | 535 | impl 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 | ||
458 | fn assoc_type_bindings_from_type_bound<'a>( | 573 | fn 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). |
488 | pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { | 602 | pub 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 { | |||
497 | pub(crate) fn field_types_query( | 611 | pub(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<()>`. |
522 | pub(crate) fn generic_predicates_for_param_query( | 639 | pub(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 | ||
536 | pub(crate) fn generic_predicates_for_param_recover( | 663 | pub(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 | ||
545 | impl TraitEnvironment { | 671 | impl 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 { | |||
557 | pub(crate) fn generic_predicates_query( | 685 | pub(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 |
569 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs { | 703 | pub(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 | ||
581 | fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { | 716 | fn 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. |
591 | fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty { | 732 | fn 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. |
598 | fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Ty { | 739 | fn 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. |
606 | fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Ty { | 750 | fn 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 | ||
624 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig { | 769 | fn 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. |
637 | fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Ty { | 782 | fn 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 | ||
647 | fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig { | 792 | fn 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. |
663 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Ty { | 806 | fn 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 | ||
674 | fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty { | 817 | fn 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 | ||
679 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { | 823 | fn 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. |
739 | pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Ty { | 885 | pub(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 | ||
747 | pub(crate) fn ty_recover(_db: &impl HirDatabase, _cycle: &[String], _def: &TyDefId) -> Ty { | 893 | pub(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 | ||
751 | pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { | 902 | pub(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 | ||
761 | pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Ty { | 912 | pub(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 | ||
767 | pub(crate) fn impl_self_ty_recover( | 921 | pub(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 | ||
775 | pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<TraitRef> { | 930 | pub(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 | ||
502 | pub fn implements_trait( | 502 | pub 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] |
1223 | fn infer_impl_generics() { | 1223 | fn infer_impl_generics_basic() { |
1224 | assert_snapshot!( | 1224 | assert_snapshot!( |
1225 | infer(r#" | 1225 | infer(r#" |
1226 | struct A<T1, T2> { | 1226 | struct 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 |