aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/lower.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-02-09 11:35:08 +0000
committerGitHub <[email protected]>2020-02-09 11:35:08 +0000
commit01836a0f35fa163025c64cabe1d0c34bb4f69c92 (patch)
treeaa1a3cf97173b2885f8b6d23002c73196f9a0b61 /crates/ra_hir_ty/src/lower.rs
parent961a69b88f923d4477ca4f746a793217a0cc8576 (diff)
parenteefe02ce6e1750b771cf99125429358e87485745 (diff)
Merge #3050
3050: Refactor type parameters, implement argument position impl trait r=matklad a=flodiebold I wanted to implement APIT by lowering to type parameters because we need to do that anyway for correctness and don't need Chalk support for it; this grew into some more wide-ranging refactoring of how type parameters are handled :sweat_smile: - use Ty::Bound instead of Ty::Param to represent polymorphism, and explicitly count binders. This gets us closer to Chalk's way of doing things, and means that we now only use Param as a placeholder for an unknown type, e.g. within a generic function. I.e. we're never using Param in a situation where we want to substitute it, and the method to do that is gone; `subst` now always works on bound variables. (This changes how the types of generic functions print; previously, you'd get something like `fn identity<i32>(T) -> T`, but now we display the substituted signature `fn identity<i32>(i32) -> i32`, which I think makes more sense.) - once we do this, it's more natural to represent `Param` by a globally unique ID; the use of indices was mostly to make substituting easier. This also means we fix the bug where `Param` loses its name when going through Chalk. - I would actually like to rename `Param` to `Placeholder` to better reflect its use and get closer to Chalk, but I'll leave that to a follow-up. - introduce a context for type lowering, to allow lowering `impl Trait` to different things depending on where we are. And since we have that, we can also lower type parameters directly to variables instead of placeholders. Also, we'll be able to use this later to collect diagnostics. - implement argument position impl trait by lowering it to type parameters. I've realized that this is necessary to correctly implement it; e.g. consider `fn foo(impl Display) -> impl Something`. It's observable that the return type of e.g. `foo(1u32)` unifies with itself, but doesn't unify with e.g. `foo(1i32)`; so the return type needs to be parameterized by the argument type. This fixes a few bugs as well: - type parameters 'losing' their name when they go through Chalk, as mentioned above (i.e. getting `[missing name]` somewhere) - impl trait not being considered as implementing the super traits (very noticeable for the `db` in RA) - the fact that argument impl trait was only turned into variables when the function got called caused type mismatches when the function was used as a value (fixes a few type mismatches in RA) The one thing I'm not so happy with here is how we're lowering `impl Trait` types to variables; since `TypeRef`s don't have an identity currently, we just count how many of them we have seen while going through the function signature. That's quite fragile though, since we have to do it while desugaring generics and while lowering the type signature, and in the exact same order in both cases. We could consider either giving only `TypeRef::ImplTrait` a local id, or maybe just giving all `TypeRef`s an identity after all (we talked about this before)... Follow-up tasks: - handle return position impl trait; we basically need to create a variable and some trait obligations for that variable - rename `Param` to `Placeholder` Co-authored-by: Florian Diebold <[email protected]> Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty/src/lower.rs')
-rw-r--r--crates/ra_hir_ty/src/lower.rs577
1 files changed, 370 insertions, 207 deletions
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index 2c2ecee9c..c68c5852b 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -10,12 +10,13 @@ use std::sync::Arc;
10 10
11use hir_def::{ 11use hir_def::{
12 builtin_type::BuiltinType, 12 builtin_type::BuiltinType,
13 generics::WherePredicate, 13 generics::{TypeParamProvenance, WherePredicate, WherePredicateTarget},
14 path::{GenericArg, Path, PathSegment, PathSegments}, 14 path::{GenericArg, Path, PathSegment, PathSegments},
15 resolver::{HasResolver, Resolver, TypeNs}, 15 resolver::{HasResolver, Resolver, TypeNs},
16 type_ref::{TypeBound, TypeRef}, 16 type_ref::{TypeBound, TypeRef},
17 AdtId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, 17 AdtId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId,
18 LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId, 18 LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
19 VariantId,
19}; 20};
20use ra_arena::map::ArenaMap; 21use ra_arena::map::ArenaMap;
21use ra_db::CrateId; 22use ra_db::CrateId;
@@ -27,63 +28,158 @@ use crate::{
27 all_super_traits, associated_type_by_name_including_super_traits, generics, make_mut_slice, 28 all_super_traits, associated_type_by_name_including_super_traits, generics, make_mut_slice,
28 variant_data, 29 variant_data,
29 }, 30 },
30 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, 31 Binders, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, ProjectionTy, Substs,
31 Ty, TypeCtor, TypeWalk, 32 TraitEnvironment, TraitRef, Ty, TypeCtor,
32}; 33};
33 34
35#[derive(Debug)]
36pub struct TyLoweringContext<'a, DB: HirDatabase> {
37 pub db: &'a DB,
38 pub resolver: &'a Resolver,
39 /// Note: Conceptually, it's thinkable that we could be in a location where
40 /// some type params should be represented as placeholders, and others
41 /// should be converted to variables. I think in practice, this isn't
42 /// possible currently, so this should be fine for now.
43 pub type_param_mode: TypeParamLoweringMode,
44 pub impl_trait_mode: ImplTraitLoweringMode,
45 pub impl_trait_counter: std::cell::Cell<u16>,
46}
47
48impl<'a, DB: HirDatabase> TyLoweringContext<'a, DB> {
49 pub fn new(db: &'a DB, resolver: &'a Resolver) -> Self {
50 let impl_trait_counter = std::cell::Cell::new(0);
51 let impl_trait_mode = ImplTraitLoweringMode::Disallowed;
52 let type_param_mode = TypeParamLoweringMode::Placeholder;
53 Self { db, resolver, impl_trait_mode, impl_trait_counter, type_param_mode }
54 }
55
56 pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
57 Self { impl_trait_mode, ..self }
58 }
59
60 pub fn with_type_param_mode(self, type_param_mode: TypeParamLoweringMode) -> Self {
61 Self { type_param_mode, ..self }
62 }
63}
64
65#[derive(Copy, Clone, Debug, PartialEq, Eq)]
66pub enum ImplTraitLoweringMode {
67 /// `impl Trait` gets lowered into an opaque type that doesn't unify with
68 /// anything except itself. This is used in places where values flow 'out',
69 /// i.e. for arguments of the function we're currently checking, and return
70 /// types of functions we're calling.
71 Opaque,
72 /// `impl Trait` gets lowered into a type variable. Used for argument
73 /// position impl Trait when inside the respective function, since it allows
74 /// us to support that without Chalk.
75 Param,
76 /// `impl Trait` gets lowered into a variable that can unify with some
77 /// type. This is used in places where values flow 'in', i.e. for arguments
78 /// of functions we're calling, and the return type of the function we're
79 /// currently checking.
80 Variable,
81 /// `impl Trait` is disallowed and will be an error.
82 Disallowed,
83}
84
85#[derive(Copy, Clone, Debug, PartialEq, Eq)]
86pub enum TypeParamLoweringMode {
87 Placeholder,
88 Variable,
89}
90
34impl Ty { 91impl Ty {
35 pub fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { 92 pub fn from_hir(ctx: &TyLoweringContext<'_, impl HirDatabase>, type_ref: &TypeRef) -> Self {
36 match type_ref { 93 match type_ref {
37 TypeRef::Never => Ty::simple(TypeCtor::Never), 94 TypeRef::Never => Ty::simple(TypeCtor::Never),
38 TypeRef::Tuple(inner) => { 95 TypeRef::Tuple(inner) => {
39 let inner_tys: Arc<[Ty]> = 96 let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect();
40 inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect();
41 Ty::apply( 97 Ty::apply(
42 TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, 98 TypeCtor::Tuple { cardinality: inner_tys.len() as u16 },
43 Substs(inner_tys), 99 Substs(inner_tys),
44 ) 100 )
45 } 101 }
46 TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path), 102 TypeRef::Path(path) => Ty::from_hir_path(ctx, path),
47 TypeRef::RawPtr(inner, mutability) => { 103 TypeRef::RawPtr(inner, mutability) => {
48 let inner_ty = Ty::from_hir(db, resolver, inner); 104 let inner_ty = Ty::from_hir(ctx, inner);
49 Ty::apply_one(TypeCtor::RawPtr(*mutability), inner_ty) 105 Ty::apply_one(TypeCtor::RawPtr(*mutability), inner_ty)
50 } 106 }
51 TypeRef::Array(inner) => { 107 TypeRef::Array(inner) => {
52 let inner_ty = Ty::from_hir(db, resolver, inner); 108 let inner_ty = Ty::from_hir(ctx, inner);
53 Ty::apply_one(TypeCtor::Array, inner_ty) 109 Ty::apply_one(TypeCtor::Array, inner_ty)
54 } 110 }
55 TypeRef::Slice(inner) => { 111 TypeRef::Slice(inner) => {
56 let inner_ty = Ty::from_hir(db, resolver, inner); 112 let inner_ty = Ty::from_hir(ctx, inner);
57 Ty::apply_one(TypeCtor::Slice, inner_ty) 113 Ty::apply_one(TypeCtor::Slice, inner_ty)
58 } 114 }
59 TypeRef::Reference(inner, mutability) => { 115 TypeRef::Reference(inner, mutability) => {
60 let inner_ty = Ty::from_hir(db, resolver, inner); 116 let inner_ty = Ty::from_hir(ctx, inner);
61 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) 117 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty)
62 } 118 }
63 TypeRef::Placeholder => Ty::Unknown, 119 TypeRef::Placeholder => Ty::Unknown,
64 TypeRef::Fn(params) => { 120 TypeRef::Fn(params) => {
65 let sig = Substs(params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect()); 121 let sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect());
66 Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig) 122 Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig)
67 } 123 }
68 TypeRef::DynTrait(bounds) => { 124 TypeRef::DynTrait(bounds) => {
69 let self_ty = Ty::Bound(0); 125 let self_ty = Ty::Bound(0);
70 let predicates = bounds 126 let predicates = bounds
71 .iter() 127 .iter()
72 .flat_map(|b| { 128 .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone()))
73 GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone())
74 })
75 .collect(); 129 .collect();
76 Ty::Dyn(predicates) 130 Ty::Dyn(predicates)
77 } 131 }
78 TypeRef::ImplTrait(bounds) => { 132 TypeRef::ImplTrait(bounds) => {
79 let self_ty = Ty::Bound(0); 133 match ctx.impl_trait_mode {
80 let predicates = bounds 134 ImplTraitLoweringMode::Opaque => {
81 .iter() 135 let self_ty = Ty::Bound(0);
82 .flat_map(|b| { 136 let predicates = bounds
83 GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone()) 137 .iter()
84 }) 138 .flat_map(|b| {
85 .collect(); 139 GenericPredicate::from_type_bound(ctx, b, self_ty.clone())
86 Ty::Opaque(predicates) 140 })
141 .collect();
142 Ty::Opaque(predicates)
143 }
144 ImplTraitLoweringMode::Param => {
145 let idx = ctx.impl_trait_counter.get();
146 ctx.impl_trait_counter.set(idx + 1);
147 if let Some(def) = ctx.resolver.generic_def() {
148 let generics = generics(ctx.db, def);
149 let param = generics
150 .iter()
151 .filter(|(_, data)| {
152 data.provenance == TypeParamProvenance::ArgumentImplTrait
153 })
154 .nth(idx as usize)
155 .map_or(Ty::Unknown, |(id, _)| Ty::Param(id));
156 param
157 } else {
158 Ty::Unknown
159 }
160 }
161 ImplTraitLoweringMode::Variable => {
162 let idx = ctx.impl_trait_counter.get();
163 ctx.impl_trait_counter.set(idx + 1);
164 let (parent_params, self_params, list_params, _impl_trait_params) =
165 if let Some(def) = ctx.resolver.generic_def() {
166 let generics = generics(ctx.db, def);
167 generics.provenance_split()
168 } else {
169 (0, 0, 0, 0)
170 };
171 Ty::Bound(
172 idx as u32
173 + parent_params as u32
174 + self_params as u32
175 + list_params as u32,
176 )
177 }
178 ImplTraitLoweringMode::Disallowed => {
179 // FIXME: report error
180 Ty::Unknown
181 }
182 }
87 } 183 }
88 TypeRef::Error => Ty::Unknown, 184 TypeRef::Error => Ty::Unknown,
89 } 185 }
@@ -93,10 +189,9 @@ impl Ty {
93 /// lower the self types of the predicates since that could lead to cycles. 189 /// lower the self types of the predicates since that could lead to cycles.
94 /// So we just check here if the `type_ref` resolves to a generic param, and which. 190 /// So we just check here if the `type_ref` resolves to a generic param, and which.
95 fn from_hir_only_param( 191 fn from_hir_only_param(
96 db: &impl HirDatabase, 192 ctx: &TyLoweringContext<'_, impl HirDatabase>,
97 resolver: &Resolver,
98 type_ref: &TypeRef, 193 type_ref: &TypeRef,
99 ) -> Option<u32> { 194 ) -> Option<TypeParamId> {
100 let path = match type_ref { 195 let path = match type_ref {
101 TypeRef::Path(path) => path, 196 TypeRef::Path(path) => path,
102 _ => return None, 197 _ => return None,
@@ -107,29 +202,26 @@ impl Ty {
107 if path.segments().len() > 1 { 202 if path.segments().len() > 1 {
108 return None; 203 return None;
109 } 204 }
110 let resolution = match resolver.resolve_path_in_type_ns(db, path.mod_path()) { 205 let resolution = match ctx.resolver.resolve_path_in_type_ns(ctx.db, path.mod_path()) {
111 Some((it, None)) => it, 206 Some((it, None)) => it,
112 _ => return None, 207 _ => return None,
113 }; 208 };
114 if let TypeNs::GenericParam(param_id) = resolution { 209 if let TypeNs::GenericParam(param_id) = resolution {
115 let generics = generics(db, resolver.generic_def().expect("generics in scope")); 210 Some(param_id)
116 let idx = generics.param_idx(param_id);
117 Some(idx)
118 } else { 211 } else {
119 None 212 None
120 } 213 }
121 } 214 }
122 215
123 pub(crate) fn from_type_relative_path( 216 pub(crate) fn from_type_relative_path(
124 db: &impl HirDatabase, 217 ctx: &TyLoweringContext<'_, impl HirDatabase>,
125 resolver: &Resolver,
126 ty: Ty, 218 ty: Ty,
127 remaining_segments: PathSegments<'_>, 219 remaining_segments: PathSegments<'_>,
128 ) -> Ty { 220 ) -> Ty {
129 if remaining_segments.len() == 1 { 221 if remaining_segments.len() == 1 {
130 // resolve unselected assoc types 222 // resolve unselected assoc types
131 let segment = remaining_segments.first().unwrap(); 223 let segment = remaining_segments.first().unwrap();
132 Ty::select_associated_type(db, resolver, ty, segment) 224 Ty::select_associated_type(ctx, ty, segment)
133 } else if remaining_segments.len() > 1 { 225 } else if remaining_segments.len() > 1 {
134 // FIXME report error (ambiguous associated type) 226 // FIXME report error (ambiguous associated type)
135 Ty::Unknown 227 Ty::Unknown
@@ -139,20 +231,18 @@ impl Ty {
139 } 231 }
140 232
141 pub(crate) fn from_partly_resolved_hir_path( 233 pub(crate) fn from_partly_resolved_hir_path(
142 db: &impl HirDatabase, 234 ctx: &TyLoweringContext<'_, impl HirDatabase>,
143 resolver: &Resolver,
144 resolution: TypeNs, 235 resolution: TypeNs,
145 resolved_segment: PathSegment<'_>, 236 resolved_segment: PathSegment<'_>,
146 remaining_segments: PathSegments<'_>, 237 remaining_segments: PathSegments<'_>,
147 ) -> Ty { 238 ) -> Ty {
148 let ty = match resolution { 239 let ty = match resolution {
149 TypeNs::TraitId(trait_) => { 240 TypeNs::TraitId(trait_) => {
150 let trait_ref = 241 let trait_ref = TraitRef::from_resolved_path(ctx, trait_, resolved_segment, None);
151 TraitRef::from_resolved_path(db, resolver, trait_, resolved_segment, None);
152 return if remaining_segments.len() == 1 { 242 return if remaining_segments.len() == 1 {
153 let segment = remaining_segments.first().unwrap(); 243 let segment = remaining_segments.first().unwrap();
154 let associated_ty = associated_type_by_name_including_super_traits( 244 let associated_ty = associated_type_by_name_including_super_traits(
155 db, 245 ctx.db,
156 trait_ref.trait_, 246 trait_ref.trait_,
157 &segment.name, 247 &segment.name,
158 ); 248 );
@@ -177,37 +267,55 @@ impl Ty {
177 }; 267 };
178 } 268 }
179 TypeNs::GenericParam(param_id) => { 269 TypeNs::GenericParam(param_id) => {
180 let generics = generics(db, resolver.generic_def().expect("generics in scope")); 270 let generics =
181 let idx = generics.param_idx(param_id); 271 generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope"));
182 // FIXME: maybe return name in resolution? 272 match ctx.type_param_mode {
183 let name = generics.param_name(param_id); 273 TypeParamLoweringMode::Placeholder => Ty::Param(param_id),
184 Ty::Param { idx, name } 274 TypeParamLoweringMode::Variable => {
275 let idx = generics.param_idx(param_id).expect("matching generics");
276 Ty::Bound(idx)
277 }
278 }
185 } 279 }
186 TypeNs::SelfType(impl_id) => db.impl_self_ty(impl_id).clone(), 280 TypeNs::SelfType(impl_id) => {
187 TypeNs::AdtSelfType(adt) => db.ty(adt.into()), 281 let generics = generics(ctx.db, impl_id.into());
188 282 let substs = match ctx.type_param_mode {
189 TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), 283 TypeParamLoweringMode::Placeholder => {
190 TypeNs::BuiltinType(it) => { 284 Substs::type_params_for_generics(&generics)
191 Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) 285 }
286 TypeParamLoweringMode::Variable => Substs::bound_vars(&generics),
287 };
288 ctx.db.impl_self_ty(impl_id).subst(&substs)
192 } 289 }
193 TypeNs::TypeAliasId(it) => { 290 TypeNs::AdtSelfType(adt) => {
194 Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) 291 let generics = generics(ctx.db, adt.into());
292 let substs = match ctx.type_param_mode {
293 TypeParamLoweringMode::Placeholder => {
294 Substs::type_params_for_generics(&generics)
295 }
296 TypeParamLoweringMode::Variable => Substs::bound_vars(&generics),
297 };
298 ctx.db.ty(adt.into()).subst(&substs)
195 } 299 }
300
301 TypeNs::AdtId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()),
302 TypeNs::BuiltinType(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()),
303 TypeNs::TypeAliasId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()),
196 // FIXME: report error 304 // FIXME: report error
197 TypeNs::EnumVariantId(_) => return Ty::Unknown, 305 TypeNs::EnumVariantId(_) => return Ty::Unknown,
198 }; 306 };
199 307
200 Ty::from_type_relative_path(db, resolver, ty, remaining_segments) 308 Ty::from_type_relative_path(ctx, ty, remaining_segments)
201 } 309 }
202 310
203 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Ty { 311 pub(crate) fn from_hir_path(ctx: &TyLoweringContext<'_, impl HirDatabase>, path: &Path) -> Ty {
204 // Resolve the path (in type namespace) 312 // Resolve the path (in type namespace)
205 if let Some(type_ref) = path.type_anchor() { 313 if let Some(type_ref) = path.type_anchor() {
206 let ty = Ty::from_hir(db, resolver, &type_ref); 314 let ty = Ty::from_hir(ctx, &type_ref);
207 return Ty::from_type_relative_path(db, resolver, ty, path.segments()); 315 return Ty::from_type_relative_path(ctx, ty, path.segments());
208 } 316 }
209 let (resolution, remaining_index) = 317 let (resolution, remaining_index) =
210 match resolver.resolve_path_in_type_ns(db, path.mod_path()) { 318 match ctx.resolver.resolve_path_in_type_ns(ctx.db, path.mod_path()) {
211 Some(it) => it, 319 Some(it) => it,
212 None => return Ty::Unknown, 320 None => return Ty::Unknown,
213 }; 321 };
@@ -218,39 +326,44 @@ impl Ty {
218 ), 326 ),
219 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)), 327 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)),
220 }; 328 };
221 Ty::from_partly_resolved_hir_path( 329 Ty::from_partly_resolved_hir_path(ctx, resolution, resolved_segment, remaining_segments)
222 db,
223 resolver,
224 resolution,
225 resolved_segment,
226 remaining_segments,
227 )
228 } 330 }
229 331
230 fn select_associated_type( 332 fn select_associated_type(
231 db: &impl HirDatabase, 333 ctx: &TyLoweringContext<'_, impl HirDatabase>,
232 resolver: &Resolver,
233 self_ty: Ty, 334 self_ty: Ty,
234 segment: PathSegment<'_>, 335 segment: PathSegment<'_>,
235 ) -> Ty { 336 ) -> Ty {
236 let param_idx = match self_ty { 337 let def = match ctx.resolver.generic_def() {
237 Ty::Param { idx, .. } => idx,
238 _ => return Ty::Unknown, // Error: Ambiguous associated type
239 };
240 let def = match resolver.generic_def() {
241 Some(def) => def, 338 Some(def) => def,
242 None => return Ty::Unknown, // this can't actually happen 339 None => return Ty::Unknown, // this can't actually happen
243 }; 340 };
244 let predicates = db.generic_predicates_for_param(def.into(), param_idx); 341 let param_id = match self_ty {
245 let traits_from_env = predicates.iter().filter_map(|pred| match pred { 342 Ty::Param(id) if ctx.type_param_mode == TypeParamLoweringMode::Placeholder => id,
246 GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), 343 Ty::Bound(idx) if ctx.type_param_mode == TypeParamLoweringMode::Variable => {
344 let generics = generics(ctx.db, def);
345 let param_id = if let Some((id, _)) = generics.iter().nth(idx as usize) {
346 id
347 } else {
348 return Ty::Unknown;
349 };
350 param_id
351 }
352 _ => return Ty::Unknown, // Error: Ambiguous associated type
353 };
354 let predicates = ctx.db.generic_predicates_for_param(param_id);
355 let traits_from_env = predicates.iter().filter_map(|pred| match &pred.value {
356 GenericPredicate::Implemented(tr) => Some(tr.trait_),
247 _ => None, 357 _ => None,
248 }); 358 });
249 let traits = traits_from_env.flat_map(|t| all_super_traits(db, t)); 359 let traits = traits_from_env.flat_map(|t| all_super_traits(ctx.db, t));
250 for t in traits { 360 for t in traits {
251 if let Some(associated_ty) = db.trait_data(t).associated_type_by_name(&segment.name) { 361 if let Some(associated_ty) = ctx.db.trait_data(t).associated_type_by_name(&segment.name)
252 let substs = 362 {
253 Substs::build_for_def(db, t).push(self_ty.clone()).fill_with_unknown().build(); 363 let substs = Substs::build_for_def(ctx.db, t)
364 .push(self_ty.clone())
365 .fill_with_unknown()
366 .build();
254 // FIXME handle type parameters on the segment 367 // FIXME handle type parameters on the segment
255 return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); 368 return Ty::Projection(ProjectionTy { associated_ty, parameters: substs });
256 } 369 }
@@ -259,8 +372,7 @@ impl Ty {
259 } 372 }
260 373
261 fn from_hir_path_inner( 374 fn from_hir_path_inner(
262 db: &impl HirDatabase, 375 ctx: &TyLoweringContext<'_, impl HirDatabase>,
263 resolver: &Resolver,
264 segment: PathSegment<'_>, 376 segment: PathSegment<'_>,
265 typable: TyDefId, 377 typable: TyDefId,
266 ) -> Ty { 378 ) -> Ty {
@@ -269,15 +381,14 @@ impl Ty {
269 TyDefId::AdtId(it) => Some(it.into()), 381 TyDefId::AdtId(it) => Some(it.into()),
270 TyDefId::TypeAliasId(it) => Some(it.into()), 382 TyDefId::TypeAliasId(it) => Some(it.into()),
271 }; 383 };
272 let substs = substs_from_path_segment(db, resolver, segment, generic_def, false); 384 let substs = substs_from_path_segment(ctx, segment, generic_def, false);
273 db.ty(typable).subst(&substs) 385 ctx.db.ty(typable).subst(&substs)
274 } 386 }
275 387
276 /// Collect generic arguments from a path into a `Substs`. See also 388 /// Collect generic arguments from a path into a `Substs`. See also
277 /// `create_substs_for_ast_path` and `def_to_ty` in rustc. 389 /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
278 pub(super) fn substs_from_path( 390 pub(super) fn substs_from_path(
279 db: &impl HirDatabase, 391 ctx: &TyLoweringContext<'_, impl HirDatabase>,
280 resolver: &Resolver,
281 path: &Path, 392 path: &Path,
282 // Note that we don't call `db.value_type(resolved)` here, 393 // Note that we don't call `db.value_type(resolved)` here,
283 // `ValueTyDefId` is just a convenient way to pass generics and 394 // `ValueTyDefId` is just a convenient way to pass generics and
@@ -305,52 +416,49 @@ impl Ty {
305 (segment, Some(var.parent.into())) 416 (segment, Some(var.parent.into()))
306 } 417 }
307 }; 418 };
308 substs_from_path_segment(db, resolver, segment, generic_def, false) 419 substs_from_path_segment(ctx, segment, generic_def, false)
309 } 420 }
310} 421}
311 422
312pub(super) fn substs_from_path_segment( 423pub(super) fn substs_from_path_segment(
313 db: &impl HirDatabase, 424 ctx: &TyLoweringContext<'_, impl HirDatabase>,
314 resolver: &Resolver,
315 segment: PathSegment<'_>, 425 segment: PathSegment<'_>,
316 def_generic: Option<GenericDefId>, 426 def_generic: Option<GenericDefId>,
317 add_self_param: bool, 427 _add_self_param: bool,
318) -> Substs { 428) -> Substs {
319 let mut substs = Vec::new(); 429 let mut substs = Vec::new();
320 let def_generics = def_generic.map(|def| generics(db, def.into())); 430 let def_generics = def_generic.map(|def| generics(ctx.db, def.into()));
321 431
322 let (total_len, parent_len, child_len) = def_generics.map_or((0, 0, 0), |g| g.len_split()); 432 let (parent_params, self_params, type_params, impl_trait_params) =
323 substs.extend(iter::repeat(Ty::Unknown).take(parent_len)); 433 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split());
324 if add_self_param { 434 substs.extend(iter::repeat(Ty::Unknown).take(parent_params));
325 // FIXME this add_self_param argument is kind of a hack: Traits have the
326 // Self type as an implicit first type parameter, but it can't be
327 // actually provided in the type arguments
328 // (well, actually sometimes it can, in the form of type-relative paths: `<Foo as Default>::default()`)
329 substs.push(Ty::Unknown);
330 }
331 if let Some(generic_args) = &segment.args_and_bindings { 435 if let Some(generic_args) = &segment.args_and_bindings {
436 if !generic_args.has_self_type {
437 substs.extend(iter::repeat(Ty::Unknown).take(self_params));
438 }
439 let expected_num =
440 if generic_args.has_self_type { self_params + type_params } else { type_params };
441 let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
332 // if args are provided, it should be all of them, but we can't rely on that 442 // if args are provided, it should be all of them, but we can't rely on that
333 let self_param_correction = if add_self_param { 1 } else { 0 }; 443 for arg in generic_args.args.iter().skip(skip).take(expected_num) {
334 let child_len = child_len - self_param_correction;
335 for arg in generic_args.args.iter().take(child_len) {
336 match arg { 444 match arg {
337 GenericArg::Type(type_ref) => { 445 GenericArg::Type(type_ref) => {
338 let ty = Ty::from_hir(db, resolver, type_ref); 446 let ty = Ty::from_hir(ctx, type_ref);
339 substs.push(ty); 447 substs.push(ty);
340 } 448 }
341 } 449 }
342 } 450 }
343 } 451 }
452 let total_len = parent_params + self_params + type_params + impl_trait_params;
344 // add placeholders for args that were not provided 453 // add placeholders for args that were not provided
345 let supplied_params = substs.len(); 454 for _ in substs.len()..total_len {
346 for _ in supplied_params..total_len {
347 substs.push(Ty::Unknown); 455 substs.push(Ty::Unknown);
348 } 456 }
349 assert_eq!(substs.len(), total_len); 457 assert_eq!(substs.len(), total_len);
350 458
351 // handle defaults 459 // handle defaults
352 if let Some(def_generic) = def_generic { 460 if let Some(def_generic) = def_generic {
353 let default_substs = db.generic_defaults(def_generic.into()); 461 let default_substs = ctx.db.generic_defaults(def_generic.into());
354 assert_eq!(substs.len(), default_substs.len()); 462 assert_eq!(substs.len(), default_substs.len());
355 463
356 for (i, default_ty) in default_substs.iter().enumerate() { 464 for (i, default_ty) in default_substs.iter().enumerate() {
@@ -365,27 +473,25 @@ pub(super) fn substs_from_path_segment(
365 473
366impl TraitRef { 474impl TraitRef {
367 fn from_path( 475 fn from_path(
368 db: &impl HirDatabase, 476 ctx: &TyLoweringContext<'_, impl HirDatabase>,
369 resolver: &Resolver,
370 path: &Path, 477 path: &Path,
371 explicit_self_ty: Option<Ty>, 478 explicit_self_ty: Option<Ty>,
372 ) -> Option<Self> { 479 ) -> Option<Self> {
373 let resolved = match resolver.resolve_path_in_type_ns_fully(db, path.mod_path())? { 480 let resolved = match ctx.resolver.resolve_path_in_type_ns_fully(ctx.db, path.mod_path())? {
374 TypeNs::TraitId(tr) => tr, 481 TypeNs::TraitId(tr) => tr,
375 _ => return None, 482 _ => return None,
376 }; 483 };
377 let segment = path.segments().last().expect("path should have at least one segment"); 484 let segment = path.segments().last().expect("path should have at least one segment");
378 Some(TraitRef::from_resolved_path(db, resolver, resolved.into(), segment, explicit_self_ty)) 485 Some(TraitRef::from_resolved_path(ctx, resolved.into(), segment, explicit_self_ty))
379 } 486 }
380 487
381 pub(crate) fn from_resolved_path( 488 pub(crate) fn from_resolved_path(
382 db: &impl HirDatabase, 489 ctx: &TyLoweringContext<'_, impl HirDatabase>,
383 resolver: &Resolver,
384 resolved: TraitId, 490 resolved: TraitId,
385 segment: PathSegment<'_>, 491 segment: PathSegment<'_>,
386 explicit_self_ty: Option<Ty>, 492 explicit_self_ty: Option<Ty>,
387 ) -> Self { 493 ) -> Self {
388 let mut substs = TraitRef::substs_from_path(db, resolver, segment, resolved); 494 let mut substs = TraitRef::substs_from_path(ctx, segment, resolved);
389 if let Some(self_ty) = explicit_self_ty { 495 if let Some(self_ty) = explicit_self_ty {
390 make_mut_slice(&mut substs.0)[0] = self_ty; 496 make_mut_slice(&mut substs.0)[0] = self_ty;
391 } 497 }
@@ -393,8 +499,7 @@ impl TraitRef {
393 } 499 }
394 500
395 fn from_hir( 501 fn from_hir(
396 db: &impl HirDatabase, 502 ctx: &TyLoweringContext<'_, impl HirDatabase>,
397 resolver: &Resolver,
398 type_ref: &TypeRef, 503 type_ref: &TypeRef,
399 explicit_self_ty: Option<Ty>, 504 explicit_self_ty: Option<Ty>,
400 ) -> Option<Self> { 505 ) -> Option<Self> {
@@ -402,28 +507,26 @@ impl TraitRef {
402 TypeRef::Path(path) => path, 507 TypeRef::Path(path) => path,
403 _ => return None, 508 _ => return None,
404 }; 509 };
405 TraitRef::from_path(db, resolver, path, explicit_self_ty) 510 TraitRef::from_path(ctx, path, explicit_self_ty)
406 } 511 }
407 512
408 fn substs_from_path( 513 fn substs_from_path(
409 db: &impl HirDatabase, 514 ctx: &TyLoweringContext<'_, impl HirDatabase>,
410 resolver: &Resolver,
411 segment: PathSegment<'_>, 515 segment: PathSegment<'_>,
412 resolved: TraitId, 516 resolved: TraitId,
413 ) -> Substs { 517 ) -> Substs {
414 let has_self_param = 518 let has_self_param =
415 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false); 519 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false);
416 substs_from_path_segment(db, resolver, segment, Some(resolved.into()), !has_self_param) 520 substs_from_path_segment(ctx, segment, Some(resolved.into()), !has_self_param)
417 } 521 }
418 522
419 pub(crate) fn from_type_bound( 523 pub(crate) fn from_type_bound(
420 db: &impl HirDatabase, 524 ctx: &TyLoweringContext<'_, impl HirDatabase>,
421 resolver: &Resolver,
422 bound: &TypeBound, 525 bound: &TypeBound,
423 self_ty: Ty, 526 self_ty: Ty,
424 ) -> Option<TraitRef> { 527 ) -> Option<TraitRef> {
425 match bound { 528 match bound {
426 TypeBound::Path(path) => TraitRef::from_path(db, resolver, path, Some(self_ty)), 529 TypeBound::Path(path) => TraitRef::from_path(ctx, path, Some(self_ty)),
427 TypeBound::Error => None, 530 TypeBound::Error => None,
428 } 531 }
429 } 532 }
@@ -431,33 +534,44 @@ impl TraitRef {
431 534
432impl GenericPredicate { 535impl GenericPredicate {
433 pub(crate) fn from_where_predicate<'a>( 536 pub(crate) fn from_where_predicate<'a>(
434 db: &'a impl HirDatabase, 537 ctx: &'a TyLoweringContext<'a, impl HirDatabase>,
435 resolver: &'a Resolver,
436 where_predicate: &'a WherePredicate, 538 where_predicate: &'a WherePredicate,
437 ) -> impl Iterator<Item = GenericPredicate> + 'a { 539 ) -> impl Iterator<Item = GenericPredicate> + 'a {
438 let self_ty = Ty::from_hir(db, resolver, &where_predicate.type_ref); 540 let self_ty = match &where_predicate.target {
439 GenericPredicate::from_type_bound(db, resolver, &where_predicate.bound, self_ty) 541 WherePredicateTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref),
542 WherePredicateTarget::TypeParam(param_id) => {
543 let generic_def = ctx.resolver.generic_def().expect("generics in scope");
544 let generics = generics(ctx.db, generic_def);
545 let param_id = hir_def::TypeParamId { parent: generic_def, local_id: *param_id };
546 match ctx.type_param_mode {
547 TypeParamLoweringMode::Placeholder => Ty::Param(param_id),
548 TypeParamLoweringMode::Variable => {
549 let idx = generics.param_idx(param_id).expect("matching generics");
550 Ty::Bound(idx)
551 }
552 }
553 }
554 };
555 GenericPredicate::from_type_bound(ctx, &where_predicate.bound, self_ty)
440 } 556 }
441 557
442 pub(crate) fn from_type_bound<'a>( 558 pub(crate) fn from_type_bound<'a>(
443 db: &'a impl HirDatabase, 559 ctx: &'a TyLoweringContext<'a, impl HirDatabase>,
444 resolver: &'a Resolver,
445 bound: &'a TypeBound, 560 bound: &'a TypeBound,
446 self_ty: Ty, 561 self_ty: Ty,
447 ) -> impl Iterator<Item = GenericPredicate> + 'a { 562 ) -> impl Iterator<Item = GenericPredicate> + 'a {
448 let trait_ref = TraitRef::from_type_bound(db, &resolver, bound, self_ty); 563 let trait_ref = TraitRef::from_type_bound(ctx, bound, self_ty);
449 iter::once(trait_ref.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented)) 564 iter::once(trait_ref.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented))
450 .chain( 565 .chain(
451 trait_ref.into_iter().flat_map(move |tr| { 566 trait_ref
452 assoc_type_bindings_from_type_bound(db, resolver, bound, tr) 567 .into_iter()
453 }), 568 .flat_map(move |tr| assoc_type_bindings_from_type_bound(ctx, bound, tr)),
454 ) 569 )
455 } 570 }
456} 571}
457 572
458fn assoc_type_bindings_from_type_bound<'a>( 573fn assoc_type_bindings_from_type_bound<'a>(
459 db: &'a impl HirDatabase, 574 ctx: &'a TyLoweringContext<'a, impl HirDatabase>,
460 resolver: &'a Resolver,
461 bound: &'a TypeBound, 575 bound: &'a TypeBound,
462 trait_ref: TraitRef, 576 trait_ref: TraitRef,
463) -> impl Iterator<Item = GenericPredicate> + 'a { 577) -> impl Iterator<Item = GenericPredicate> + 'a {
@@ -471,21 +585,21 @@ fn assoc_type_bindings_from_type_bound<'a>(
471 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) 585 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter())
472 .map(move |(name, type_ref)| { 586 .map(move |(name, type_ref)| {
473 let associated_ty = 587 let associated_ty =
474 associated_type_by_name_including_super_traits(db, trait_ref.trait_, &name); 588 associated_type_by_name_including_super_traits(ctx.db, trait_ref.trait_, &name);
475 let associated_ty = match associated_ty { 589 let associated_ty = match associated_ty {
476 None => return GenericPredicate::Error, 590 None => return GenericPredicate::Error,
477 Some(t) => t, 591 Some(t) => t,
478 }; 592 };
479 let projection_ty = 593 let projection_ty =
480 ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() }; 594 ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() };
481 let ty = Ty::from_hir(db, resolver, type_ref); 595 let ty = Ty::from_hir(ctx, type_ref);
482 let projection_predicate = ProjectionPredicate { projection_ty, ty }; 596 let projection_predicate = ProjectionPredicate { projection_ty, ty };
483 GenericPredicate::Projection(projection_predicate) 597 GenericPredicate::Projection(projection_predicate)
484 }) 598 })
485} 599}
486 600
487/// Build the signature of a callable item (function, struct or enum variant). 601/// Build the signature of a callable item (function, struct or enum variant).
488pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { 602pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> PolyFnSig {
489 match def { 603 match def {
490 CallableDef::FunctionId(f) => fn_sig_for_fn(db, f), 604 CallableDef::FunctionId(f) => fn_sig_for_fn(db, f),
491 CallableDef::StructId(s) => fn_sig_for_struct_constructor(db, s), 605 CallableDef::StructId(s) => fn_sig_for_struct_constructor(db, s),
@@ -497,16 +611,19 @@ pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig {
497pub(crate) fn field_types_query( 611pub(crate) fn field_types_query(
498 db: &impl HirDatabase, 612 db: &impl HirDatabase,
499 variant_id: VariantId, 613 variant_id: VariantId,
500) -> Arc<ArenaMap<LocalStructFieldId, Ty>> { 614) -> Arc<ArenaMap<LocalStructFieldId, Binders<Ty>>> {
501 let var_data = variant_data(db, variant_id); 615 let var_data = variant_data(db, variant_id);
502 let resolver = match variant_id { 616 let (resolver, def): (_, GenericDefId) = match variant_id {
503 VariantId::StructId(it) => it.resolver(db), 617 VariantId::StructId(it) => (it.resolver(db), it.into()),
504 VariantId::UnionId(it) => it.resolver(db), 618 VariantId::UnionId(it) => (it.resolver(db), it.into()),
505 VariantId::EnumVariantId(it) => it.parent.resolver(db), 619 VariantId::EnumVariantId(it) => (it.parent.resolver(db), it.parent.into()),
506 }; 620 };
621 let generics = generics(db, def);
507 let mut res = ArenaMap::default(); 622 let mut res = ArenaMap::default();
623 let ctx =
624 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
508 for (field_id, field_data) in var_data.fields().iter() { 625 for (field_id, field_data) in var_data.fields().iter() {
509 res.insert(field_id, Ty::from_hir(db, &resolver, &field_data.type_ref)) 626 res.insert(field_id, Binders::new(generics.len(), Ty::from_hir(&ctx, &field_data.type_ref)))
510 } 627 }
511 Arc::new(res) 628 Arc::new(res)
512} 629}
@@ -521,32 +638,43 @@ pub(crate) fn field_types_query(
521/// these are fine: `T: Foo<U::Item>, U: Foo<()>`. 638/// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
522pub(crate) fn generic_predicates_for_param_query( 639pub(crate) fn generic_predicates_for_param_query(
523 db: &impl HirDatabase, 640 db: &impl HirDatabase,
524 def: GenericDefId, 641 param_id: TypeParamId,
525 param_idx: u32, 642) -> Arc<[Binders<GenericPredicate>]> {
526) -> Arc<[GenericPredicate]> { 643 let resolver = param_id.parent.resolver(db);
527 let resolver = def.resolver(db); 644 let ctx =
645 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
646 let generics = generics(db, param_id.parent);
528 resolver 647 resolver
529 .where_predicates_in_scope() 648 .where_predicates_in_scope()
530 // we have to filter out all other predicates *first*, before attempting to lower them 649 // we have to filter out all other predicates *first*, before attempting to lower them
531 .filter(|pred| Ty::from_hir_only_param(db, &resolver, &pred.type_ref) == Some(param_idx)) 650 .filter(|pred| match &pred.target {
532 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 651 WherePredicateTarget::TypeRef(type_ref) => {
652 Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id)
653 }
654 WherePredicateTarget::TypeParam(local_id) => *local_id == param_id.local_id,
655 })
656 .flat_map(|pred| {
657 GenericPredicate::from_where_predicate(&ctx, pred)
658 .map(|p| Binders::new(generics.len(), p))
659 })
533 .collect() 660 .collect()
534} 661}
535 662
536pub(crate) fn generic_predicates_for_param_recover( 663pub(crate) fn generic_predicates_for_param_recover(
537 _db: &impl HirDatabase, 664 _db: &impl HirDatabase,
538 _cycle: &[String], 665 _cycle: &[String],
539 _def: &GenericDefId, 666 _param_id: &TypeParamId,
540 _param_idx: &u32, 667) -> Arc<[Binders<GenericPredicate>]> {
541) -> Arc<[GenericPredicate]> {
542 Arc::new([]) 668 Arc::new([])
543} 669}
544 670
545impl TraitEnvironment { 671impl TraitEnvironment {
546 pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { 672 pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> {
673 let ctx = TyLoweringContext::new(db, &resolver)
674 .with_type_param_mode(TypeParamLoweringMode::Placeholder);
547 let predicates = resolver 675 let predicates = resolver
548 .where_predicates_in_scope() 676 .where_predicates_in_scope()
549 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 677 .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred))
550 .collect::<Vec<_>>(); 678 .collect::<Vec<_>>();
551 679
552 Arc::new(TraitEnvironment { predicates }) 680 Arc::new(TraitEnvironment { predicates })
@@ -557,57 +685,74 @@ impl TraitEnvironment {
557pub(crate) fn generic_predicates_query( 685pub(crate) fn generic_predicates_query(
558 db: &impl HirDatabase, 686 db: &impl HirDatabase,
559 def: GenericDefId, 687 def: GenericDefId,
560) -> Arc<[GenericPredicate]> { 688) -> Arc<[Binders<GenericPredicate>]> {
561 let resolver = def.resolver(db); 689 let resolver = def.resolver(db);
690 let ctx =
691 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
692 let generics = generics(db, def);
562 resolver 693 resolver
563 .where_predicates_in_scope() 694 .where_predicates_in_scope()
564 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 695 .flat_map(|pred| {
696 GenericPredicate::from_where_predicate(&ctx, pred)
697 .map(|p| Binders::new(generics.len(), p))
698 })
565 .collect() 699 .collect()
566} 700}
567 701
568/// Resolve the default type params from generics 702/// Resolve the default type params from generics
569pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs { 703pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs {
570 let resolver = def.resolver(db); 704 let resolver = def.resolver(db);
705 let ctx = TyLoweringContext::new(db, &resolver);
571 let generic_params = generics(db, def.into()); 706 let generic_params = generics(db, def.into());
572 707
573 let defaults = generic_params 708 let defaults = generic_params
574 .iter() 709 .iter()
575 .map(|(_idx, p)| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(db, &resolver, t))) 710 .map(|(_idx, p)| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(&ctx, t)))
576 .collect(); 711 .collect();
577 712
578 Substs(defaults) 713 Substs(defaults)
579} 714}
580 715
581fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { 716fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> PolyFnSig {
582 let data = db.function_data(def); 717 let data = db.function_data(def);
583 let resolver = def.resolver(db); 718 let resolver = def.resolver(db);
584 let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); 719 let ctx_params = TyLoweringContext::new(db, &resolver)
585 let ret = Ty::from_hir(db, &resolver, &data.ret_type); 720 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
586 FnSig::from_params_and_return(params, ret) 721 .with_type_param_mode(TypeParamLoweringMode::Variable);
722 let params = data.params.iter().map(|tr| Ty::from_hir(&ctx_params, tr)).collect::<Vec<_>>();
723 let ctx_ret = ctx_params.with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
724 let ret = Ty::from_hir(&ctx_ret, &data.ret_type);
725 let generics = generics(db, def.into());
726 let num_binders = generics.len();
727 Binders::new(num_binders, FnSig::from_params_and_return(params, ret))
587} 728}
588 729
589/// Build the declared type of a function. This should not need to look at the 730/// Build the declared type of a function. This should not need to look at the
590/// function body. 731/// function body.
591fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty { 732fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Binders<Ty> {
592 let generics = generics(db, def.into()); 733 let generics = generics(db, def.into());
593 let substs = Substs::identity(&generics); 734 let substs = Substs::bound_vars(&generics);
594 Ty::apply(TypeCtor::FnDef(def.into()), substs) 735 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs))
595} 736}
596 737
597/// Build the declared type of a const. 738/// Build the declared type of a const.
598fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Ty { 739fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Binders<Ty> {
599 let data = db.const_data(def); 740 let data = db.const_data(def);
741 let generics = generics(db, def.into());
600 let resolver = def.resolver(db); 742 let resolver = def.resolver(db);
743 let ctx =
744 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
601 745
602 Ty::from_hir(db, &resolver, &data.type_ref) 746 Binders::new(generics.len(), Ty::from_hir(&ctx, &data.type_ref))
603} 747}
604 748
605/// Build the declared type of a static. 749/// Build the declared type of a static.
606fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Ty { 750fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Binders<Ty> {
607 let data = db.static_data(def); 751 let data = db.static_data(def);
608 let resolver = def.resolver(db); 752 let resolver = def.resolver(db);
753 let ctx = TyLoweringContext::new(db, &resolver);
609 754
610 Ty::from_hir(db, &resolver, &data.type_ref) 755 Binders::new(0, Ty::from_hir(&ctx, &data.type_ref))
611} 756}
612 757
613/// Build the declared type of a static. 758/// Build the declared type of a static.
@@ -621,68 +766,69 @@ fn type_for_builtin(def: BuiltinType) -> Ty {
621 }) 766 })
622} 767}
623 768
624fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig { 769fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> PolyFnSig {
625 let struct_data = db.struct_data(def.into()); 770 let struct_data = db.struct_data(def.into());
626 let fields = struct_data.variant_data.fields(); 771 let fields = struct_data.variant_data.fields();
627 let resolver = def.resolver(db); 772 let resolver = def.resolver(db);
628 let params = fields 773 let ctx =
629 .iter() 774 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
630 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 775 let params =
631 .collect::<Vec<_>>(); 776 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
632 let ret = type_for_adt(db, def.into()); 777 let ret = type_for_adt(db, def.into());
633 FnSig::from_params_and_return(params, ret) 778 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value))
634} 779}
635 780
636/// Build the type of a tuple struct constructor. 781/// Build the type of a tuple struct constructor.
637fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Ty { 782fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Binders<Ty> {
638 let struct_data = db.struct_data(def.into()); 783 let struct_data = db.struct_data(def.into());
639 if struct_data.variant_data.is_unit() { 784 if struct_data.variant_data.is_unit() {
640 return type_for_adt(db, def.into()); // Unit struct 785 return type_for_adt(db, def.into()); // Unit struct
641 } 786 }
642 let generics = generics(db, def.into()); 787 let generics = generics(db, def.into());
643 let substs = Substs::identity(&generics); 788 let substs = Substs::bound_vars(&generics);
644 Ty::apply(TypeCtor::FnDef(def.into()), substs) 789 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs))
645} 790}
646 791
647fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig { 792fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> PolyFnSig {
648 let enum_data = db.enum_data(def.parent); 793 let enum_data = db.enum_data(def.parent);
649 let var_data = &enum_data.variants[def.local_id]; 794 let var_data = &enum_data.variants[def.local_id];
650 let fields = var_data.variant_data.fields(); 795 let fields = var_data.variant_data.fields();
651 let resolver = def.parent.resolver(db); 796 let resolver = def.parent.resolver(db);
652 let params = fields 797 let ctx =
653 .iter() 798 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
654 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 799 let params =
655 .collect::<Vec<_>>(); 800 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
656 let generics = generics(db, def.parent.into()); 801 let ret = type_for_adt(db, def.parent.into());
657 let substs = Substs::identity(&generics); 802 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value))
658 let ret = type_for_adt(db, def.parent.into()).subst(&substs);
659 FnSig::from_params_and_return(params, ret)
660} 803}
661 804
662/// Build the type of a tuple enum variant constructor. 805/// Build the type of a tuple enum variant constructor.
663fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Ty { 806fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Binders<Ty> {
664 let enum_data = db.enum_data(def.parent); 807 let enum_data = db.enum_data(def.parent);
665 let var_data = &enum_data.variants[def.local_id].variant_data; 808 let var_data = &enum_data.variants[def.local_id].variant_data;
666 if var_data.is_unit() { 809 if var_data.is_unit() {
667 return type_for_adt(db, def.parent.into()); // Unit variant 810 return type_for_adt(db, def.parent.into()); // Unit variant
668 } 811 }
669 let generics = generics(db, def.parent.into()); 812 let generics = generics(db, def.parent.into());
670 let substs = Substs::identity(&generics); 813 let substs = Substs::bound_vars(&generics);
671 Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) 814 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs))
672} 815}
673 816
674fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty { 817fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Binders<Ty> {
675 let generics = generics(db, adt.into()); 818 let generics = generics(db, adt.into());
676 Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) 819 let substs = Substs::bound_vars(&generics);
820 Binders::new(substs.len(), Ty::apply(TypeCtor::Adt(adt), substs))
677} 821}
678 822
679fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { 823fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Binders<Ty> {
680 let generics = generics(db, t.into()); 824 let generics = generics(db, t.into());
681 let resolver = t.resolver(db); 825 let resolver = t.resolver(db);
826 let ctx =
827 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
682 let type_ref = &db.type_alias_data(t).type_ref; 828 let type_ref = &db.type_alias_data(t).type_ref;
683 let substs = Substs::identity(&generics); 829 let substs = Substs::bound_vars(&generics);
684 let inner = Ty::from_hir(db, &resolver, type_ref.as_ref().unwrap_or(&TypeRef::Error)); 830 let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error));
685 inner.subst(&substs) 831 Binders::new(substs.len(), inner)
686} 832}
687 833
688#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 834#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -736,19 +882,24 @@ impl_froms!(ValueTyDefId: FunctionId, StructId, EnumVariantId, ConstId, StaticId
736/// `struct Foo(usize)`, we have two types: The type of the struct itself, and 882/// `struct Foo(usize)`, we have two types: The type of the struct itself, and
737/// the constructor function `(usize) -> Foo` which lives in the values 883/// the constructor function `(usize) -> Foo` which lives in the values
738/// namespace. 884/// namespace.
739pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Ty { 885pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Binders<Ty> {
740 match def { 886 match def {
741 TyDefId::BuiltinType(it) => type_for_builtin(it), 887 TyDefId::BuiltinType(it) => Binders::new(0, type_for_builtin(it)),
742 TyDefId::AdtId(it) => type_for_adt(db, it), 888 TyDefId::AdtId(it) => type_for_adt(db, it),
743 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), 889 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
744 } 890 }
745} 891}
746 892
747pub(crate) fn ty_recover(_db: &impl HirDatabase, _cycle: &[String], _def: &TyDefId) -> Ty { 893pub(crate) fn ty_recover(db: &impl HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> {
748 Ty::Unknown 894 let num_binders = match *def {
895 TyDefId::BuiltinType(_) => 0,
896 TyDefId::AdtId(it) => generics(db, it.into()).len(),
897 TyDefId::TypeAliasId(it) => generics(db, it.into()).len(),
898 };
899 Binders::new(num_binders, Ty::Unknown)
749} 900}
750 901
751pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { 902pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
752 match def { 903 match def {
753 ValueTyDefId::FunctionId(it) => type_for_fn(db, it), 904 ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
754 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it), 905 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
@@ -758,24 +909,36 @@ pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty {
758 } 909 }
759} 910}
760 911
761pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Ty { 912pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Binders<Ty> {
762 let impl_data = db.impl_data(impl_id); 913 let impl_data = db.impl_data(impl_id);
763 let resolver = impl_id.resolver(db); 914 let resolver = impl_id.resolver(db);
764 Ty::from_hir(db, &resolver, &impl_data.target_type) 915 let generics = generics(db, impl_id.into());
916 let ctx =
917 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
918 Binders::new(generics.len(), Ty::from_hir(&ctx, &impl_data.target_type))
765} 919}
766 920
767pub(crate) fn impl_self_ty_recover( 921pub(crate) fn impl_self_ty_recover(
768 _db: &impl HirDatabase, 922 db: &impl HirDatabase,
769 _cycle: &[String], 923 _cycle: &[String],
770 _impl_id: &ImplId, 924 impl_id: &ImplId,
771) -> Ty { 925) -> Binders<Ty> {
772 Ty::Unknown 926 let generics = generics(db, (*impl_id).into());
927 Binders::new(generics.len(), Ty::Unknown)
773} 928}
774 929
775pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<TraitRef> { 930pub(crate) fn impl_trait_query(
931 db: &impl HirDatabase,
932 impl_id: ImplId,
933) -> Option<Binders<TraitRef>> {
776 let impl_data = db.impl_data(impl_id); 934 let impl_data = db.impl_data(impl_id);
777 let resolver = impl_id.resolver(db); 935 let resolver = impl_id.resolver(db);
936 let ctx =
937 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
778 let self_ty = db.impl_self_ty(impl_id); 938 let self_ty = db.impl_self_ty(impl_id);
779 let target_trait = impl_data.target_trait.as_ref()?; 939 let target_trait = impl_data.target_trait.as_ref()?;
780 TraitRef::from_hir(db, &resolver, target_trait, Some(self_ty.clone())) 940 Some(Binders::new(
941 self_ty.num_binders,
942 TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value.clone()))?,
943 ))
781} 944}