aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/lower.rs')
-rw-r--r--crates/hir_ty/src/lower.rs705
1 files changed, 358 insertions, 347 deletions
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 5fa83567b..c32dca9d7 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -8,7 +8,7 @@
8use std::{iter, sync::Arc}; 8use std::{iter, sync::Arc};
9 9
10use base_db::CrateId; 10use base_db::CrateId;
11use chalk_ir::Mutability; 11use chalk_ir::{cast::Cast, Mutability};
12use hir_def::{ 12use hir_def::{
13 adt::StructKind, 13 adt::StructKind,
14 builtin_type::BuiltinType, 14 builtin_type::BuiltinType,
@@ -27,13 +27,15 @@ use stdx::impl_from;
27 27
28use crate::{ 28use crate::{
29 db::HirDatabase, 29 db::HirDatabase,
30 to_assoc_type_id, to_placeholder_idx,
31 traits::chalk::{Interner, ToChalk},
30 utils::{ 32 utils::{
31 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
32 make_mut_slice, variant_data, 34 make_mut_slice, variant_data,
33 }, 35 },
34 AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, 36 AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate,
35 OpaqueTy, OpaqueTyId, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, 37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait,
36 ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, 38 ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk,
37}; 39};
38 40
39#[derive(Debug)] 41#[derive(Debug)]
@@ -138,69 +140,71 @@ pub enum TypeParamLoweringMode {
138 Variable, 140 Variable,
139} 141}
140 142
141impl Ty { 143impl<'a> TyLoweringContext<'a> {
142 pub fn from_hir(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> Self { 144 pub fn lower_ty(&self, type_ref: &TypeRef) -> Ty {
143 Ty::from_hir_ext(ctx, type_ref).0 145 self.lower_ty_ext(type_ref).0
144 } 146 }
145 pub fn from_hir_ext(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> (Self, Option<TypeNs>) { 147
148 fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
146 let mut res = None; 149 let mut res = None;
147 let ty = match type_ref { 150 let ty = match type_ref {
148 TypeRef::Never => Ty::Never, 151 TypeRef::Never => TyKind::Never.intern(&Interner),
149 TypeRef::Tuple(inner) => { 152 TypeRef::Tuple(inner) => {
150 let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect(); 153 let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| self.lower_ty(tr)).collect();
151 Ty::Tuple(inner_tys.len(), Substs(inner_tys)) 154 TyKind::Tuple(inner_tys.len(), Substs(inner_tys)).intern(&Interner)
152 } 155 }
153 TypeRef::Path(path) => { 156 TypeRef::Path(path) => {
154 let (ty, res_) = Ty::from_hir_path(ctx, path); 157 let (ty, res_) = self.lower_path(path);
155 res = res_; 158 res = res_;
156 ty 159 ty
157 } 160 }
158 TypeRef::RawPtr(inner, mutability) => { 161 TypeRef::RawPtr(inner, mutability) => {
159 let inner_ty = Ty::from_hir(ctx, inner); 162 let inner_ty = self.lower_ty(inner);
160 Ty::Raw(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty)) 163 TyKind::Raw(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty))
164 .intern(&Interner)
161 } 165 }
162 TypeRef::Array(inner) => { 166 TypeRef::Array(inner) => {
163 let inner_ty = Ty::from_hir(ctx, inner); 167 let inner_ty = self.lower_ty(inner);
164 Ty::Array(Substs::single(inner_ty)) 168 TyKind::Array(Substs::single(inner_ty)).intern(&Interner)
165 } 169 }
166 TypeRef::Slice(inner) => { 170 TypeRef::Slice(inner) => {
167 let inner_ty = Ty::from_hir(ctx, inner); 171 let inner_ty = self.lower_ty(inner);
168 Ty::Slice(Substs::single(inner_ty)) 172 TyKind::Slice(Substs::single(inner_ty)).intern(&Interner)
169 } 173 }
170 TypeRef::Reference(inner, _, mutability) => { 174 TypeRef::Reference(inner, _, mutability) => {
171 let inner_ty = Ty::from_hir(ctx, inner); 175 let inner_ty = self.lower_ty(inner);
172 Ty::Ref(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty)) 176 TyKind::Ref(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty))
177 .intern(&Interner)
173 } 178 }
174 TypeRef::Placeholder => Ty::Unknown, 179 TypeRef::Placeholder => TyKind::Unknown.intern(&Interner),
175 TypeRef::Fn(params, is_varargs) => { 180 TypeRef::Fn(params, is_varargs) => {
176 let substs = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); 181 let substs = Substs(params.iter().map(|tr| self.lower_ty(tr)).collect());
177 Ty::Function(FnPointer { 182 TyKind::Function(FnPointer {
178 num_args: substs.len() - 1, 183 num_args: substs.len() - 1,
179 sig: FnSig { variadic: *is_varargs }, 184 sig: FnSig { variadic: *is_varargs },
180 substs, 185 substs,
181 }) 186 })
187 .intern(&Interner)
182 } 188 }
183 TypeRef::DynTrait(bounds) => { 189 TypeRef::DynTrait(bounds) => {
184 let self_ty = Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 190 let self_ty =
185 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { 191 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
186 bounds 192 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
187 .iter() 193 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone())).collect()
188 .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone()))
189 .collect()
190 }); 194 });
191 Ty::Dyn(predicates) 195 TyKind::Dyn(predicates).intern(&Interner)
192 } 196 }
193 TypeRef::ImplTrait(bounds) => { 197 TypeRef::ImplTrait(bounds) => {
194 match ctx.impl_trait_mode { 198 match self.impl_trait_mode {
195 ImplTraitLoweringMode::Opaque => { 199 ImplTraitLoweringMode::Opaque => {
196 let idx = ctx.impl_trait_counter.get(); 200 let idx = self.impl_trait_counter.get();
197 ctx.impl_trait_counter.set(idx + 1); 201 self.impl_trait_counter.set(idx + 1);
198 202
199 assert!(idx as usize == ctx.opaque_type_data.borrow().len()); 203 assert!(idx as usize == self.opaque_type_data.borrow().len());
200 // this dance is to make sure the data is in the right 204 // this dance is to make sure the data is in the right
201 // place even if we encounter more opaque types while 205 // place even if we encounter more opaque types while
202 // lowering the bounds 206 // lowering the bounds
203 ctx.opaque_type_data 207 self.opaque_type_data
204 .borrow_mut() 208 .borrow_mut()
205 .push(ReturnTypeImplTrait { bounds: Binders::new(1, Vec::new()) }); 209 .push(ReturnTypeImplTrait { bounds: Binders::new(1, Vec::new()) });
206 // We don't want to lower the bounds inside the binders 210 // We don't want to lower the bounds inside the binders
@@ -212,65 +216,67 @@ impl Ty {
212 // other, but separately. So if the `T` refers to a type 216 // other, but separately. So if the `T` refers to a type
213 // parameter of the outer function, it's just one binder 217 // parameter of the outer function, it's just one binder
214 // away instead of two. 218 // away instead of two.
215 let actual_opaque_type_data = ctx 219 let actual_opaque_type_data = self
216 .with_debruijn(DebruijnIndex::INNERMOST, |ctx| { 220 .with_debruijn(DebruijnIndex::INNERMOST, |ctx| {
217 ReturnTypeImplTrait::from_hir(ctx, &bounds) 221 ctx.lower_impl_trait(&bounds)
218 }); 222 });
219 ctx.opaque_type_data.borrow_mut()[idx as usize] = actual_opaque_type_data; 223 self.opaque_type_data.borrow_mut()[idx as usize] = actual_opaque_type_data;
220 224
221 let func = match ctx.resolver.generic_def() { 225 let func = match self.resolver.generic_def() {
222 Some(GenericDefId::FunctionId(f)) => f, 226 Some(GenericDefId::FunctionId(f)) => f,
223 _ => panic!("opaque impl trait lowering in non-function"), 227 _ => panic!("opaque impl trait lowering in non-function"),
224 }; 228 };
225 let impl_trait_id = OpaqueTyId::ReturnTypeImplTrait(func, idx); 229 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx);
226 let generics = generics(ctx.db.upcast(), func.into()); 230 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
227 let parameters = Substs::bound_vars(&generics, ctx.in_binders); 231 let generics = generics(self.db.upcast(), func.into());
228 Ty::Alias(AliasTy::Opaque(OpaqueTy { 232 let parameters = Substs::bound_vars(&generics, self.in_binders);
229 opaque_ty_id: impl_trait_id, 233 TyKind::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id, parameters }))
230 parameters, 234 .intern(&Interner)
231 }))
232 } 235 }
233 ImplTraitLoweringMode::Param => { 236 ImplTraitLoweringMode::Param => {
234 let idx = ctx.impl_trait_counter.get(); 237 let idx = self.impl_trait_counter.get();
235 // FIXME we're probably doing something wrong here 238 // FIXME we're probably doing something wrong here
236 ctx.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16); 239 self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
237 if let Some(def) = ctx.resolver.generic_def() { 240 if let Some(def) = self.resolver.generic_def() {
238 let generics = generics(ctx.db.upcast(), def); 241 let generics = generics(self.db.upcast(), def);
239 let param = generics 242 let param = generics
240 .iter() 243 .iter()
241 .filter(|(_, data)| { 244 .filter(|(_, data)| {
242 data.provenance == TypeParamProvenance::ArgumentImplTrait 245 data.provenance == TypeParamProvenance::ArgumentImplTrait
243 }) 246 })
244 .nth(idx as usize) 247 .nth(idx as usize)
245 .map_or(Ty::Unknown, |(id, _)| Ty::Placeholder(id)); 248 .map_or(TyKind::Unknown, |(id, _)| {
246 param 249 TyKind::Placeholder(to_placeholder_idx(self.db, id))
250 });
251 param.intern(&Interner)
247 } else { 252 } else {
248 Ty::Unknown 253 TyKind::Unknown.intern(&Interner)
249 } 254 }
250 } 255 }
251 ImplTraitLoweringMode::Variable => { 256 ImplTraitLoweringMode::Variable => {
252 let idx = ctx.impl_trait_counter.get(); 257 let idx = self.impl_trait_counter.get();
253 // FIXME we're probably doing something wrong here 258 // FIXME we're probably doing something wrong here
254 ctx.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16); 259 self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
255 let (parent_params, self_params, list_params, _impl_trait_params) = 260 let (parent_params, self_params, list_params, _impl_trait_params) =
256 if let Some(def) = ctx.resolver.generic_def() { 261 if let Some(def) = self.resolver.generic_def() {
257 let generics = generics(ctx.db.upcast(), def); 262 let generics = generics(self.db.upcast(), def);
258 generics.provenance_split() 263 generics.provenance_split()
259 } else { 264 } else {
260 (0, 0, 0, 0) 265 (0, 0, 0, 0)
261 }; 266 };
262 Ty::BoundVar(BoundVar::new( 267 TyKind::BoundVar(BoundVar::new(
263 ctx.in_binders, 268 self.in_binders,
264 idx as usize + parent_params + self_params + list_params, 269 idx as usize + parent_params + self_params + list_params,
265 )) 270 ))
271 .intern(&Interner)
266 } 272 }
267 ImplTraitLoweringMode::Disallowed => { 273 ImplTraitLoweringMode::Disallowed => {
268 // FIXME: report error 274 // FIXME: report error
269 Ty::Unknown 275 TyKind::Unknown.intern(&Interner)
270 } 276 }
271 } 277 }
272 } 278 }
273 TypeRef::Error => Ty::Unknown, 279 TypeRef::Error => TyKind::Unknown.intern(&Interner),
274 }; 280 };
275 (ty, res) 281 (ty, res)
276 } 282 }
@@ -278,7 +284,7 @@ impl Ty {
278 /// This is only for `generic_predicates_for_param`, where we can't just 284 /// This is only for `generic_predicates_for_param`, where we can't just
279 /// lower the self types of the predicates since that could lead to cycles. 285 /// lower the self types of the predicates since that could lead to cycles.
280 /// So we just check here if the `type_ref` resolves to a generic param, and which. 286 /// So we just check here if the `type_ref` resolves to a generic param, and which.
281 fn from_hir_only_param(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> Option<TypeParamId> { 287 fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeParamId> {
282 let path = match type_ref { 288 let path = match type_ref {
283 TypeRef::Path(path) => path, 289 TypeRef::Path(path) => path,
284 _ => return None, 290 _ => return None,
@@ -290,7 +296,7 @@ impl Ty {
290 return None; 296 return None;
291 } 297 }
292 let resolution = 298 let resolution =
293 match ctx.resolver.resolve_path_in_type_ns(ctx.db.upcast(), path.mod_path()) { 299 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
294 Some((it, None)) => it, 300 Some((it, None)) => it,
295 _ => return None, 301 _ => return None,
296 }; 302 };
@@ -301,8 +307,8 @@ impl Ty {
301 } 307 }
302 } 308 }
303 309
304 pub(crate) fn from_type_relative_path( 310 pub(crate) fn lower_ty_relative_path(
305 ctx: &TyLoweringContext<'_>, 311 &self,
306 ty: Ty, 312 ty: Ty,
307 // We need the original resolution to lower `Self::AssocTy` correctly 313 // We need the original resolution to lower `Self::AssocTy` correctly
308 res: Option<TypeNs>, 314 res: Option<TypeNs>,
@@ -311,17 +317,17 @@ impl Ty {
311 if remaining_segments.len() == 1 { 317 if remaining_segments.len() == 1 {
312 // resolve unselected assoc types 318 // resolve unselected assoc types
313 let segment = remaining_segments.first().unwrap(); 319 let segment = remaining_segments.first().unwrap();
314 (Ty::select_associated_type(ctx, res, segment), None) 320 (self.select_associated_type(res, segment), None)
315 } else if remaining_segments.len() > 1 { 321 } else if remaining_segments.len() > 1 {
316 // FIXME report error (ambiguous associated type) 322 // FIXME report error (ambiguous associated type)
317 (Ty::Unknown, None) 323 (TyKind::Unknown.intern(&Interner), None)
318 } else { 324 } else {
319 (ty, res) 325 (ty, res)
320 } 326 }
321 } 327 }
322 328
323 pub(crate) fn from_partly_resolved_hir_path( 329 pub(crate) fn lower_partly_resolved_path(
324 ctx: &TyLoweringContext<'_>, 330 &self,
325 resolution: TypeNs, 331 resolution: TypeNs,
326 resolved_segment: PathSegment<'_>, 332 resolved_segment: PathSegment<'_>,
327 remaining_segments: PathSegments<'_>, 333 remaining_segments: PathSegments<'_>,
@@ -331,103 +337,109 @@ impl Ty {
331 TypeNs::TraitId(trait_) => { 337 TypeNs::TraitId(trait_) => {
332 // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there 338 // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there
333 let self_ty = if remaining_segments.len() == 0 { 339 let self_ty = if remaining_segments.len() == 0 {
334 Some(Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))) 340 Some(
341 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
342 .intern(&Interner),
343 )
335 } else { 344 } else {
336 None 345 None
337 }; 346 };
338 let trait_ref = 347 let trait_ref =
339 TraitRef::from_resolved_path(ctx, trait_, resolved_segment, self_ty); 348 self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, self_ty);
340 let ty = if remaining_segments.len() == 1 { 349 let ty = if remaining_segments.len() == 1 {
341 let segment = remaining_segments.first().unwrap(); 350 let segment = remaining_segments.first().unwrap();
342 let found = associated_type_by_name_including_super_traits( 351 let found = associated_type_by_name_including_super_traits(
343 ctx.db, 352 self.db,
344 trait_ref, 353 trait_ref,
345 &segment.name, 354 &segment.name,
346 ); 355 );
347 match found { 356 match found {
348 Some((super_trait_ref, associated_ty)) => { 357 Some((super_trait_ref, associated_ty)) => {
349 // FIXME handle type parameters on the segment 358 // FIXME handle type parameters on the segment
350 Ty::Alias(AliasTy::Projection(ProjectionTy { 359 TyKind::Alias(AliasTy::Projection(ProjectionTy {
351 associated_ty, 360 associated_ty: to_assoc_type_id(associated_ty),
352 parameters: super_trait_ref.substs, 361 parameters: super_trait_ref.substs,
353 })) 362 }))
363 .intern(&Interner)
354 } 364 }
355 None => { 365 None => {
356 // FIXME: report error (associated type not found) 366 // FIXME: report error (associated type not found)
357 Ty::Unknown 367 TyKind::Unknown.intern(&Interner)
358 } 368 }
359 } 369 }
360 } else if remaining_segments.len() > 1 { 370 } else if remaining_segments.len() > 1 {
361 // FIXME report error (ambiguous associated type) 371 // FIXME report error (ambiguous associated type)
362 Ty::Unknown 372 TyKind::Unknown.intern(&Interner)
363 } else { 373 } else {
364 Ty::Dyn(Arc::new([GenericPredicate::Implemented(trait_ref)])) 374 TyKind::Dyn(Arc::new([GenericPredicate::Implemented(trait_ref)]))
375 .intern(&Interner)
365 }; 376 };
366 return (ty, None); 377 return (ty, None);
367 } 378 }
368 TypeNs::GenericParam(param_id) => { 379 TypeNs::GenericParam(param_id) => {
369 let generics = generics( 380 let generics = generics(
370 ctx.db.upcast(), 381 self.db.upcast(),
371 ctx.resolver.generic_def().expect("generics in scope"), 382 self.resolver.generic_def().expect("generics in scope"),
372 ); 383 );
373 match ctx.type_param_mode { 384 match self.type_param_mode {
374 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), 385 TypeParamLoweringMode::Placeholder => {
386 TyKind::Placeholder(to_placeholder_idx(self.db, param_id))
387 }
375 TypeParamLoweringMode::Variable => { 388 TypeParamLoweringMode::Variable => {
376 let idx = generics.param_idx(param_id).expect("matching generics"); 389 let idx = generics.param_idx(param_id).expect("matching generics");
377 Ty::BoundVar(BoundVar::new(ctx.in_binders, idx)) 390 TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
378 } 391 }
379 } 392 }
393 .intern(&Interner)
380 } 394 }
381 TypeNs::SelfType(impl_id) => { 395 TypeNs::SelfType(impl_id) => {
382 let generics = generics(ctx.db.upcast(), impl_id.into()); 396 let generics = generics(self.db.upcast(), impl_id.into());
383 let substs = match ctx.type_param_mode { 397 let substs = match self.type_param_mode {
384 TypeParamLoweringMode::Placeholder => { 398 TypeParamLoweringMode::Placeholder => {
385 Substs::type_params_for_generics(&generics) 399 Substs::type_params_for_generics(self.db, &generics)
386 } 400 }
387 TypeParamLoweringMode::Variable => { 401 TypeParamLoweringMode::Variable => {
388 Substs::bound_vars(&generics, ctx.in_binders) 402 Substs::bound_vars(&generics, self.in_binders)
389 } 403 }
390 }; 404 };
391 ctx.db.impl_self_ty(impl_id).subst(&substs) 405 self.db.impl_self_ty(impl_id).subst(&substs)
392 } 406 }
393 TypeNs::AdtSelfType(adt) => { 407 TypeNs::AdtSelfType(adt) => {
394 let generics = generics(ctx.db.upcast(), adt.into()); 408 let generics = generics(self.db.upcast(), adt.into());
395 let substs = match ctx.type_param_mode { 409 let substs = match self.type_param_mode {
396 TypeParamLoweringMode::Placeholder => { 410 TypeParamLoweringMode::Placeholder => {
397 Substs::type_params_for_generics(&generics) 411 Substs::type_params_for_generics(self.db, &generics)
398 } 412 }
399 TypeParamLoweringMode::Variable => { 413 TypeParamLoweringMode::Variable => {
400 Substs::bound_vars(&generics, ctx.in_binders) 414 Substs::bound_vars(&generics, self.in_binders)
401 } 415 }
402 }; 416 };
403 ctx.db.ty(adt.into()).subst(&substs) 417 self.db.ty(adt.into()).subst(&substs)
404 } 418 }
405 419
406 TypeNs::AdtId(it) => { 420 TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args),
407 Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args)
408 }
409 TypeNs::BuiltinType(it) => { 421 TypeNs::BuiltinType(it) => {
410 Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args) 422 self.lower_path_inner(resolved_segment, it.into(), infer_args)
411 } 423 }
412 TypeNs::TypeAliasId(it) => { 424 TypeNs::TypeAliasId(it) => {
413 Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args) 425 self.lower_path_inner(resolved_segment, it.into(), infer_args)
414 } 426 }
415 // FIXME: report error 427 // FIXME: report error
416 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), 428 TypeNs::EnumVariantId(_) => return (TyKind::Unknown.intern(&Interner), None),
417 }; 429 };
418 Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments) 430 self.lower_ty_relative_path(ty, Some(resolution), remaining_segments)
419 } 431 }
420 432
421 pub(crate) fn from_hir_path(ctx: &TyLoweringContext<'_>, path: &Path) -> (Ty, Option<TypeNs>) { 433 pub(crate) fn lower_path(&self, path: &Path) -> (Ty, Option<TypeNs>) {
422 // Resolve the path (in type namespace) 434 // Resolve the path (in type namespace)
423 if let Some(type_ref) = path.type_anchor() { 435 if let Some(type_ref) = path.type_anchor() {
424 let (ty, res) = Ty::from_hir_ext(ctx, &type_ref); 436 let (ty, res) = self.lower_ty_ext(&type_ref);
425 return Ty::from_type_relative_path(ctx, ty, res, path.segments()); 437 return self.lower_ty_relative_path(ty, res, path.segments());
426 } 438 }
427 let (resolution, remaining_index) = 439 let (resolution, remaining_index) =
428 match ctx.resolver.resolve_path_in_type_ns(ctx.db.upcast(), path.mod_path()) { 440 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
429 Some(it) => it, 441 Some(it) => it,
430 None => return (Ty::Unknown, None), 442 None => return (TyKind::Unknown.intern(&Interner), None),
431 }; 443 };
432 let (resolved_segment, remaining_segments) = match remaining_index { 444 let (resolved_segment, remaining_segments) = match remaining_index {
433 None => ( 445 None => (
@@ -436,31 +448,23 @@ impl Ty {
436 ), 448 ),
437 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)), 449 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)),
438 }; 450 };
439 Ty::from_partly_resolved_hir_path( 451 self.lower_partly_resolved_path(resolution, resolved_segment, remaining_segments, false)
440 ctx,
441 resolution,
442 resolved_segment,
443 remaining_segments,
444 false,
445 )
446 } 452 }
447 453
448 fn select_associated_type( 454 fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
449 ctx: &TyLoweringContext<'_>,
450 res: Option<TypeNs>,
451 segment: PathSegment<'_>,
452 ) -> Ty {
453 if let Some(res) = res { 455 if let Some(res) = res {
454 let ty = 456 let ty = associated_type_shorthand_candidates(
455 associated_type_shorthand_candidates(ctx.db, res, move |name, t, associated_ty| { 457 self.db,
458 res,
459 move |name, t, associated_ty| {
456 if name == segment.name { 460 if name == segment.name {
457 let substs = match ctx.type_param_mode { 461 let substs = match self.type_param_mode {
458 TypeParamLoweringMode::Placeholder => { 462 TypeParamLoweringMode::Placeholder => {
459 // if we're lowering to placeholders, we have to put 463 // if we're lowering to placeholders, we have to put
460 // them in now 464 // them in now
461 let s = Substs::type_params( 465 let s = Substs::type_params(
462 ctx.db, 466 self.db,
463 ctx.resolver.generic_def().expect( 467 self.resolver.generic_def().expect(
464 "there should be generics if there's a generic param", 468 "there should be generics if there's a generic param",
465 ), 469 ),
466 ); 470 );
@@ -470,25 +474,29 @@ impl Ty {
470 }; 474 };
471 // We need to shift in the bound vars, since 475 // We need to shift in the bound vars, since
472 // associated_type_shorthand_candidates does not do that 476 // associated_type_shorthand_candidates does not do that
473 let substs = substs.shift_bound_vars(ctx.in_binders); 477 let substs = substs.shift_bound_vars(self.in_binders);
474 // FIXME handle type parameters on the segment 478 // FIXME handle type parameters on the segment
475 return Some(Ty::Alias(AliasTy::Projection(ProjectionTy { 479 return Some(
476 associated_ty, 480 TyKind::Alias(AliasTy::Projection(ProjectionTy {
477 parameters: substs, 481 associated_ty: to_assoc_type_id(associated_ty),
478 }))); 482 parameters: substs,
483 }))
484 .intern(&Interner),
485 );
479 } 486 }
480 487
481 None 488 None
482 }); 489 },
490 );
483 491
484 ty.unwrap_or(Ty::Unknown) 492 ty.unwrap_or(TyKind::Unknown.intern(&Interner))
485 } else { 493 } else {
486 Ty::Unknown 494 TyKind::Unknown.intern(&Interner)
487 } 495 }
488 } 496 }
489 497
490 fn from_hir_path_inner( 498 fn lower_path_inner(
491 ctx: &TyLoweringContext<'_>, 499 &self,
492 segment: PathSegment<'_>, 500 segment: PathSegment<'_>,
493 typeable: TyDefId, 501 typeable: TyDefId,
494 infer_args: bool, 502 infer_args: bool,
@@ -498,14 +506,14 @@ impl Ty {
498 TyDefId::AdtId(it) => Some(it.into()), 506 TyDefId::AdtId(it) => Some(it.into()),
499 TyDefId::TypeAliasId(it) => Some(it.into()), 507 TyDefId::TypeAliasId(it) => Some(it.into()),
500 }; 508 };
501 let substs = substs_from_path_segment(ctx, segment, generic_def, infer_args); 509 let substs = self.substs_from_path_segment(segment, generic_def, infer_args);
502 ctx.db.ty(typeable).subst(&substs) 510 self.db.ty(typeable).subst(&substs)
503 } 511 }
504 512
505 /// Collect generic arguments from a path into a `Substs`. See also 513 /// Collect generic arguments from a path into a `Substs`. See also
506 /// `create_substs_for_ast_path` and `def_to_ty` in rustc. 514 /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
507 pub(super) fn substs_from_path( 515 pub(super) fn substs_from_path(
508 ctx: &TyLoweringContext<'_>, 516 &self,
509 path: &Path, 517 path: &Path,
510 // Note that we don't call `db.value_type(resolved)` here, 518 // Note that we don't call `db.value_type(resolved)` here,
511 // `ValueTyDefId` is just a convenient way to pass generics and 519 // `ValueTyDefId` is just a convenient way to pass generics and
@@ -535,169 +543,161 @@ impl Ty {
535 (segment, Some(var.parent.into())) 543 (segment, Some(var.parent.into()))
536 } 544 }
537 }; 545 };
538 substs_from_path_segment(ctx, segment, generic_def, infer_args) 546 self.substs_from_path_segment(segment, generic_def, infer_args)
539 } 547 }
540}
541 548
542fn substs_from_path_segment( 549 fn substs_from_path_segment(
543 ctx: &TyLoweringContext<'_>, 550 &self,
544 segment: PathSegment<'_>, 551 segment: PathSegment<'_>,
545 def_generic: Option<GenericDefId>, 552 def_generic: Option<GenericDefId>,
546 infer_args: bool, 553 infer_args: bool,
547) -> Substs { 554 ) -> Substs {
548 let mut substs = Vec::new(); 555 let mut substs = Vec::new();
549 let def_generics = def_generic.map(|def| generics(ctx.db.upcast(), def)); 556 let def_generics = def_generic.map(|def| generics(self.db.upcast(), def));
550 557
551 let (parent_params, self_params, type_params, impl_trait_params) = 558 let (parent_params, self_params, type_params, impl_trait_params) =
552 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split()); 559 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split());
553 let total_len = parent_params + self_params + type_params + impl_trait_params; 560 let total_len = parent_params + self_params + type_params + impl_trait_params;
554 561
555 substs.extend(iter::repeat(Ty::Unknown).take(parent_params)); 562 substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(parent_params));
556 563
557 let mut had_explicit_type_args = false; 564 let mut had_explicit_type_args = false;
558 565
559 if let Some(generic_args) = &segment.args_and_bindings { 566 if let Some(generic_args) = &segment.args_and_bindings {
560 if !generic_args.has_self_type { 567 if !generic_args.has_self_type {
561 substs.extend(iter::repeat(Ty::Unknown).take(self_params)); 568 substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(self_params));
562 } 569 }
563 let expected_num = 570 let expected_num =
564 if generic_args.has_self_type { self_params + type_params } else { type_params }; 571 if generic_args.has_self_type { self_params + type_params } else { type_params };
565 let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 }; 572 let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
566 // if args are provided, it should be all of them, but we can't rely on that 573 // if args are provided, it should be all of them, but we can't rely on that
567 for arg in generic_args 574 for arg in generic_args
568 .args 575 .args
569 .iter() 576 .iter()
570 .filter(|arg| matches!(arg, GenericArg::Type(_))) 577 .filter(|arg| matches!(arg, GenericArg::Type(_)))
571 .skip(skip) 578 .skip(skip)
572 .take(expected_num) 579 .take(expected_num)
573 { 580 {
574 match arg { 581 match arg {
575 GenericArg::Type(type_ref) => { 582 GenericArg::Type(type_ref) => {
576 had_explicit_type_args = true; 583 had_explicit_type_args = true;
577 let ty = Ty::from_hir(ctx, type_ref); 584 let ty = self.lower_ty(type_ref);
578 substs.push(ty); 585 substs.push(ty);
586 }
587 GenericArg::Lifetime(_) => {}
579 } 588 }
580 GenericArg::Lifetime(_) => {}
581 } 589 }
582 } 590 }
583 }
584 591
585 // handle defaults. In expression or pattern path segments without 592 // handle defaults. In expression or pattern path segments without
586 // explicitly specified type arguments, missing type arguments are inferred 593 // explicitly specified type arguments, missing type arguments are inferred
587 // (i.e. defaults aren't used). 594 // (i.e. defaults aren't used).
588 if !infer_args || had_explicit_type_args { 595 if !infer_args || had_explicit_type_args {
589 if let Some(def_generic) = def_generic { 596 if let Some(def_generic) = def_generic {
590 let defaults = ctx.db.generic_defaults(def_generic); 597 let defaults = self.db.generic_defaults(def_generic);
591 assert_eq!(total_len, defaults.len()); 598 assert_eq!(total_len, defaults.len());
592 599
593 for default_ty in defaults.iter().skip(substs.len()) { 600 for default_ty in defaults.iter().skip(substs.len()) {
594 // each default can depend on the previous parameters 601 // each default can depend on the previous parameters
595 let substs_so_far = Substs(substs.clone().into()); 602 let substs_so_far = Substs(substs.clone().into());
596 substs.push(default_ty.clone().subst(&substs_so_far)); 603 substs.push(default_ty.clone().subst(&substs_so_far));
604 }
597 } 605 }
598 } 606 }
599 }
600 607
601 // add placeholders for args that were not provided 608 // add placeholders for args that were not provided
602 // FIXME: emit diagnostics in contexts where this is not allowed 609 // FIXME: emit diagnostics in contexts where this is not allowed
603 for _ in substs.len()..total_len { 610 for _ in substs.len()..total_len {
604 substs.push(Ty::Unknown); 611 substs.push(TyKind::Unknown.intern(&Interner));
605 } 612 }
606 assert_eq!(substs.len(), total_len); 613 assert_eq!(substs.len(), total_len);
607 614
608 Substs(substs.into()) 615 Substs(substs.into())
609} 616 }
610 617
611impl TraitRef { 618 fn lower_trait_ref_from_path(
612 fn from_path( 619 &self,
613 ctx: &TyLoweringContext<'_>,
614 path: &Path, 620 path: &Path,
615 explicit_self_ty: Option<Ty>, 621 explicit_self_ty: Option<Ty>,
616 ) -> Option<Self> { 622 ) -> Option<TraitRef> {
617 let resolved = 623 let resolved =
618 match ctx.resolver.resolve_path_in_type_ns_fully(ctx.db.upcast(), path.mod_path())? { 624 match self.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), path.mod_path())? {
619 TypeNs::TraitId(tr) => tr, 625 TypeNs::TraitId(tr) => tr,
620 _ => return None, 626 _ => return None,
621 }; 627 };
622 let segment = path.segments().last().expect("path should have at least one segment"); 628 let segment = path.segments().last().expect("path should have at least one segment");
623 Some(TraitRef::from_resolved_path(ctx, resolved, segment, explicit_self_ty)) 629 Some(self.lower_trait_ref_from_resolved_path(resolved, segment, explicit_self_ty))
624 } 630 }
625 631
626 pub(crate) fn from_resolved_path( 632 pub(crate) fn lower_trait_ref_from_resolved_path(
627 ctx: &TyLoweringContext<'_>, 633 &self,
628 resolved: TraitId, 634 resolved: TraitId,
629 segment: PathSegment<'_>, 635 segment: PathSegment<'_>,
630 explicit_self_ty: Option<Ty>, 636 explicit_self_ty: Option<Ty>,
631 ) -> Self { 637 ) -> TraitRef {
632 let mut substs = TraitRef::substs_from_path(ctx, segment, resolved); 638 let mut substs = self.trait_ref_substs_from_path(segment, resolved);
633 if let Some(self_ty) = explicit_self_ty { 639 if let Some(self_ty) = explicit_self_ty {
634 make_mut_slice(&mut substs.0)[0] = self_ty; 640 make_mut_slice(&mut substs.0)[0] = self_ty;
635 } 641 }
636 TraitRef { trait_: resolved, substs } 642 TraitRef { trait_: resolved, substs }
637 } 643 }
638 644
639 fn from_hir( 645 fn lower_trait_ref(
640 ctx: &TyLoweringContext<'_>, 646 &self,
641 type_ref: &TypeRef, 647 type_ref: &TypeRef,
642 explicit_self_ty: Option<Ty>, 648 explicit_self_ty: Option<Ty>,
643 ) -> Option<Self> { 649 ) -> Option<TraitRef> {
644 let path = match type_ref { 650 let path = match type_ref {
645 TypeRef::Path(path) => path, 651 TypeRef::Path(path) => path,
646 _ => return None, 652 _ => return None,
647 }; 653 };
648 TraitRef::from_path(ctx, path, explicit_self_ty) 654 self.lower_trait_ref_from_path(path, explicit_self_ty)
649 } 655 }
650 656
651 fn substs_from_path( 657 fn trait_ref_substs_from_path(&self, segment: PathSegment<'_>, resolved: TraitId) -> Substs {
652 ctx: &TyLoweringContext<'_>, 658 self.substs_from_path_segment(segment, Some(resolved.into()), false)
653 segment: PathSegment<'_>,
654 resolved: TraitId,
655 ) -> Substs {
656 substs_from_path_segment(ctx, segment, Some(resolved.into()), false)
657 } 659 }
658}
659 660
660impl GenericPredicate { 661 pub(crate) fn lower_where_predicate(
661 pub(crate) fn from_where_predicate<'a>( 662 &'a self,
662 ctx: &'a TyLoweringContext<'a>,
663 where_predicate: &'a WherePredicate, 663 where_predicate: &'a WherePredicate,
664 ) -> impl Iterator<Item = GenericPredicate> + 'a { 664 ) -> impl Iterator<Item = GenericPredicate> + 'a {
665 match where_predicate { 665 match where_predicate {
666 WherePredicate::ForLifetime { target, bound, .. } 666 WherePredicate::ForLifetime { target, bound, .. }
667 | WherePredicate::TypeBound { target, bound } => { 667 | WherePredicate::TypeBound { target, bound } => {
668 let self_ty = match target { 668 let self_ty = match target {
669 WherePredicateTypeTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref), 669 WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
670 WherePredicateTypeTarget::TypeParam(param_id) => { 670 WherePredicateTypeTarget::TypeParam(param_id) => {
671 let generic_def = ctx.resolver.generic_def().expect("generics in scope"); 671 let generic_def = self.resolver.generic_def().expect("generics in scope");
672 let generics = generics(ctx.db.upcast(), generic_def); 672 let generics = generics(self.db.upcast(), generic_def);
673 let param_id = 673 let param_id =
674 hir_def::TypeParamId { parent: generic_def, local_id: *param_id }; 674 hir_def::TypeParamId { parent: generic_def, local_id: *param_id };
675 match ctx.type_param_mode { 675 let placeholder = to_placeholder_idx(self.db, param_id);
676 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), 676 match self.type_param_mode {
677 TypeParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder),
677 TypeParamLoweringMode::Variable => { 678 TypeParamLoweringMode::Variable => {
678 let idx = generics.param_idx(param_id).expect("matching generics"); 679 let idx = generics.param_idx(param_id).expect("matching generics");
679 Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx)) 680 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
680 } 681 }
681 } 682 }
683 .intern(&Interner)
682 } 684 }
683 }; 685 };
684 GenericPredicate::from_type_bound(ctx, bound, self_ty) 686 self.lower_type_bound(bound, self_ty).collect::<Vec<_>>().into_iter()
685 .collect::<Vec<_>>()
686 .into_iter()
687 } 687 }
688 WherePredicate::Lifetime { .. } => vec![].into_iter(), 688 WherePredicate::Lifetime { .. } => vec![].into_iter(),
689 } 689 }
690 } 690 }
691 691
692 pub(crate) fn from_type_bound<'a>( 692 pub(crate) fn lower_type_bound(
693 ctx: &'a TyLoweringContext<'a>, 693 &'a self,
694 bound: &'a TypeBound, 694 bound: &'a TypeBound,
695 self_ty: Ty, 695 self_ty: Ty,
696 ) -> impl Iterator<Item = GenericPredicate> + 'a { 696 ) -> impl Iterator<Item = GenericPredicate> + 'a {
697 let mut bindings = None; 697 let mut bindings = None;
698 let trait_ref = match bound { 698 let trait_ref = match bound {
699 TypeBound::Path(path) => { 699 TypeBound::Path(path) => {
700 bindings = TraitRef::from_path(ctx, path, Some(self_ty)); 700 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
701 Some( 701 Some(
702 bindings.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented), 702 bindings.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented),
703 ) 703 )
@@ -708,64 +708,62 @@ impl GenericPredicate {
708 trait_ref.into_iter().chain( 708 trait_ref.into_iter().chain(
709 bindings 709 bindings
710 .into_iter() 710 .into_iter()
711 .flat_map(move |tr| assoc_type_bindings_from_type_bound(ctx, bound, tr)), 711 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)),
712 ) 712 )
713 } 713 }
714}
715 714
716fn assoc_type_bindings_from_type_bound<'a>( 715 fn assoc_type_bindings_from_type_bound(
717 ctx: &'a TyLoweringContext<'a>, 716 &'a self,
718 bound: &'a TypeBound, 717 bound: &'a TypeBound,
719 trait_ref: TraitRef, 718 trait_ref: TraitRef,
720) -> impl Iterator<Item = GenericPredicate> + 'a { 719 ) -> impl Iterator<Item = GenericPredicate> + 'a {
721 let last_segment = match bound { 720 let last_segment = match bound {
722 TypeBound::Path(path) => path.segments().last(), 721 TypeBound::Path(path) => path.segments().last(),
723 TypeBound::Error | TypeBound::Lifetime(_) => None, 722 TypeBound::Error | TypeBound::Lifetime(_) => None,
724 }; 723 };
725 last_segment 724 last_segment
726 .into_iter() 725 .into_iter()
727 .flat_map(|segment| segment.args_and_bindings.into_iter()) 726 .flat_map(|segment| segment.args_and_bindings.into_iter())
728 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) 727 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter())
729 .flat_map(move |binding| { 728 .flat_map(move |binding| {
730 let found = associated_type_by_name_including_super_traits( 729 let found = associated_type_by_name_including_super_traits(
731 ctx.db, 730 self.db,
732 trait_ref.clone(), 731 trait_ref.clone(),
733 &binding.name, 732 &binding.name,
734 ); 733 );
735 let (super_trait_ref, associated_ty) = match found { 734 let (super_trait_ref, associated_ty) = match found {
736 None => return SmallVec::<[GenericPredicate; 1]>::new(), 735 None => return SmallVec::<[GenericPredicate; 1]>::new(),
737 Some(t) => t, 736 Some(t) => t,
738 }; 737 };
739 let projection_ty = ProjectionTy { associated_ty, parameters: super_trait_ref.substs }; 738 let projection_ty = ProjectionTy {
740 let mut preds = SmallVec::with_capacity( 739 associated_ty: to_assoc_type_id(associated_ty),
741 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(), 740 parameters: super_trait_ref.substs,
742 ); 741 };
743 if let Some(type_ref) = &binding.type_ref { 742 let mut preds = SmallVec::with_capacity(
744 let ty = Ty::from_hir(ctx, type_ref); 743 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
745 let projection_predicate = 744 );
746 ProjectionPredicate { projection_ty: projection_ty.clone(), ty }; 745 if let Some(type_ref) = &binding.type_ref {
747 preds.push(GenericPredicate::Projection(projection_predicate)); 746 let ty = self.lower_ty(type_ref);
748 } 747 let projection_predicate =
749 for bound in &binding.bounds { 748 ProjectionPredicate { projection_ty: projection_ty.clone(), ty };
750 preds.extend(GenericPredicate::from_type_bound( 749 preds.push(GenericPredicate::Projection(projection_predicate));
751 ctx, 750 }
752 bound, 751 for bound in &binding.bounds {
753 Ty::Alias(AliasTy::Projection(projection_ty.clone())), 752 preds.extend(self.lower_type_bound(
754 )); 753 bound,
755 } 754 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(&Interner),
756 preds 755 ));
757 }) 756 }
758} 757 preds
758 })
759 }
759 760
760impl ReturnTypeImplTrait { 761 fn lower_impl_trait(&self, bounds: &[TypeBound]) -> ReturnTypeImplTrait {
761 fn from_hir(ctx: &TyLoweringContext, bounds: &[TypeBound]) -> Self {
762 cov_mark::hit!(lower_rpit); 762 cov_mark::hit!(lower_rpit);
763 let self_ty = Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 763 let self_ty =
764 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { 764 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
765 bounds 765 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
766 .iter() 766 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone())).collect()
767 .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone()))
768 .collect()
769 }); 767 });
770 ReturnTypeImplTrait { bounds: Binders::new(1, predicates) } 768 ReturnTypeImplTrait { bounds: Binders::new(1, predicates) }
771 } 769 }
@@ -861,7 +859,7 @@ pub(crate) fn field_types_query(
861 let ctx = 859 let ctx =
862 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 860 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
863 for (field_id, field_data) in var_data.fields().iter() { 861 for (field_id, field_data) in var_data.fields().iter() {
864 res.insert(field_id, Binders::new(generics.len(), Ty::from_hir(&ctx, &field_data.type_ref))) 862 res.insert(field_id, Binders::new(generics.len(), ctx.lower_ty(&field_data.type_ref)))
865 } 863 }
866 Arc::new(res) 864 Arc::new(res)
867} 865}
@@ -889,16 +887,13 @@ pub(crate) fn generic_predicates_for_param_query(
889 WherePredicate::ForLifetime { target, .. } 887 WherePredicate::ForLifetime { target, .. }
890 | WherePredicate::TypeBound { target, .. } => match target { 888 | WherePredicate::TypeBound { target, .. } => match target {
891 WherePredicateTypeTarget::TypeRef(type_ref) => { 889 WherePredicateTypeTarget::TypeRef(type_ref) => {
892 Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id) 890 ctx.lower_ty_only_param(type_ref) == Some(param_id)
893 } 891 }
894 WherePredicateTypeTarget::TypeParam(local_id) => *local_id == param_id.local_id, 892 WherePredicateTypeTarget::TypeParam(local_id) => *local_id == param_id.local_id,
895 }, 893 },
896 WherePredicate::Lifetime { .. } => false, 894 WherePredicate::Lifetime { .. } => false,
897 }) 895 })
898 .flat_map(|pred| { 896 .flat_map(|pred| ctx.lower_where_predicate(pred).map(|p| Binders::new(generics.len(), p)))
899 GenericPredicate::from_where_predicate(&ctx, pred)
900 .map(|p| Binders::new(generics.len(), p))
901 })
902 .collect() 897 .collect()
903} 898}
904 899
@@ -910,41 +905,55 @@ pub(crate) fn generic_predicates_for_param_recover(
910 Arc::new([]) 905 Arc::new([])
911} 906}
912 907
913impl TraitEnvironment { 908pub(crate) fn trait_environment_query(
914 pub fn lower(db: &dyn HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { 909 db: &dyn HirDatabase,
915 let ctx = TyLoweringContext::new(db, &resolver) 910 def: GenericDefId,
916 .with_type_param_mode(TypeParamLoweringMode::Placeholder); 911) -> Arc<TraitEnvironment> {
917 let mut predicates = resolver 912 let resolver = def.resolver(db.upcast());
918 .where_predicates_in_scope() 913 let ctx = TyLoweringContext::new(db, &resolver)
919 .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) 914 .with_type_param_mode(TypeParamLoweringMode::Placeholder);
920 .collect::<Vec<_>>(); 915 let mut traits_in_scope = Vec::new();
921 916 let mut clauses = Vec::new();
922 if let Some(def) = resolver.generic_def() { 917 for pred in resolver.where_predicates_in_scope() {
923 let container: Option<AssocContainerId> = match def { 918 for pred in ctx.lower_where_predicate(pred) {
924 // FIXME: is there a function for this? 919 if pred.is_error() {
925 GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container), 920 continue;
926 GenericDefId::AdtId(_) => None,
927 GenericDefId::TraitId(_) => None,
928 GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container),
929 GenericDefId::ImplId(_) => None,
930 GenericDefId::EnumVariantId(_) => None,
931 GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container),
932 };
933 if let Some(AssocContainerId::TraitId(trait_id)) = container {
934 // add `Self: Trait<T1, T2, ...>` to the environment in trait
935 // function default implementations (and hypothetical code
936 // inside consts or type aliases)
937 cov_mark::hit!(trait_self_implements_self);
938 let substs = Substs::type_params(db, trait_id);
939 let trait_ref = TraitRef { trait_: trait_id, substs };
940 let pred = GenericPredicate::Implemented(trait_ref);
941
942 predicates.push(pred);
943 } 921 }
922 if let GenericPredicate::Implemented(tr) = &pred {
923 traits_in_scope.push((tr.self_ty().clone(), tr.trait_));
924 }
925 let program_clause: chalk_ir::ProgramClause<Interner> =
926 pred.clone().to_chalk(db).cast(&Interner);
927 clauses.push(program_clause.into_from_env_clause(&Interner));
944 } 928 }
929 }
945 930
946 Arc::new(TraitEnvironment { predicates }) 931 let container: Option<AssocContainerId> = match def {
932 // FIXME: is there a function for this?
933 GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
934 GenericDefId::AdtId(_) => None,
935 GenericDefId::TraitId(_) => None,
936 GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container),
937 GenericDefId::ImplId(_) => None,
938 GenericDefId::EnumVariantId(_) => None,
939 GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container),
940 };
941 if let Some(AssocContainerId::TraitId(trait_id)) = container {
942 // add `Self: Trait<T1, T2, ...>` to the environment in trait
943 // function default implementations (and hypothetical code
944 // inside consts or type aliases)
945 cov_mark::hit!(trait_self_implements_self);
946 let substs = Substs::type_params(db, trait_id);
947 let trait_ref = TraitRef { trait_: trait_id, substs };
948 let pred = GenericPredicate::Implemented(trait_ref);
949 let program_clause: chalk_ir::ProgramClause<Interner> =
950 pred.clone().to_chalk(db).cast(&Interner);
951 clauses.push(program_clause.into_from_env_clause(&Interner));
947 } 952 }
953
954 let env = chalk_ir::Environment::new(&Interner).add_clauses(&Interner, clauses);
955
956 Arc::new(TraitEnvironment { traits_from_clauses: traits_in_scope, env })
948} 957}
949 958
950/// Resolve the where clause(s) of an item with generics. 959/// Resolve the where clause(s) of an item with generics.
@@ -958,10 +967,7 @@ pub(crate) fn generic_predicates_query(
958 let generics = generics(db.upcast(), def); 967 let generics = generics(db.upcast(), def);
959 resolver 968 resolver
960 .where_predicates_in_scope() 969 .where_predicates_in_scope()
961 .flat_map(|pred| { 970 .flat_map(|pred| ctx.lower_where_predicate(pred).map(|p| Binders::new(generics.len(), p)))
962 GenericPredicate::from_where_predicate(&ctx, pred)
963 .map(|p| Binders::new(generics.len(), p))
964 })
965 .collect() 971 .collect()
966} 972}
967 973
@@ -979,17 +985,18 @@ pub(crate) fn generic_defaults_query(
979 .iter() 985 .iter()
980 .enumerate() 986 .enumerate()
981 .map(|(idx, (_, p))| { 987 .map(|(idx, (_, p))| {
982 let mut ty = p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(&ctx, t)); 988 let mut ty =
989 p.default.as_ref().map_or(TyKind::Unknown.intern(&Interner), |t| ctx.lower_ty(t));
983 990
984 // Each default can only refer to previous parameters. 991 // Each default can only refer to previous parameters.
985 ty.walk_mut_binders( 992 ty.walk_mut_binders(
986 &mut |ty, binders| match ty { 993 &mut |ty, binders| match &mut ty.0 {
987 Ty::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { 994 TyKind::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => {
988 if *index >= idx { 995 if *index >= idx {
989 // type variable default referring to parameter coming 996 // type variable default referring to parameter coming
990 // after it. This is forbidden (FIXME: report 997 // after it. This is forbidden (FIXME: report
991 // diagnostic) 998 // diagnostic)
992 *ty = Ty::Unknown; 999 *ty = TyKind::Unknown.intern(&Interner);
993 } 1000 }
994 } 1001 }
995 _ => {} 1002 _ => {}
@@ -1010,11 +1017,11 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1010 let ctx_params = TyLoweringContext::new(db, &resolver) 1017 let ctx_params = TyLoweringContext::new(db, &resolver)
1011 .with_impl_trait_mode(ImplTraitLoweringMode::Variable) 1018 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
1012 .with_type_param_mode(TypeParamLoweringMode::Variable); 1019 .with_type_param_mode(TypeParamLoweringMode::Variable);
1013 let params = data.params.iter().map(|tr| Ty::from_hir(&ctx_params, tr)).collect::<Vec<_>>(); 1020 let params = data.params.iter().map(|tr| (&ctx_params).lower_ty(tr)).collect::<Vec<_>>();
1014 let ctx_ret = TyLoweringContext::new(db, &resolver) 1021 let ctx_ret = TyLoweringContext::new(db, &resolver)
1015 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) 1022 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1016 .with_type_param_mode(TypeParamLoweringMode::Variable); 1023 .with_type_param_mode(TypeParamLoweringMode::Variable);
1017 let ret = Ty::from_hir(&ctx_ret, &data.ret_type); 1024 let ret = (&ctx_ret).lower_ty(&data.ret_type);
1018 let generics = generics(db.upcast(), def.into()); 1025 let generics = generics(db.upcast(), def.into());
1019 let num_binders = generics.len(); 1026 let num_binders = generics.len();
1020 Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs)) 1027 Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs))
@@ -1025,7 +1032,10 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1025fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { 1032fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1026 let generics = generics(db.upcast(), def.into()); 1033 let generics = generics(db.upcast(), def.into());
1027 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1034 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1028 Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) 1035 Binders::new(
1036 substs.len(),
1037 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner),
1038 )
1029} 1039}
1030 1040
1031/// Build the declared type of a const. 1041/// Build the declared type of a const.
@@ -1036,7 +1046,7 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
1036 let ctx = 1046 let ctx =
1037 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1047 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1038 1048
1039 Binders::new(generics.len(), Ty::from_hir(&ctx, &data.type_ref)) 1049 Binders::new(generics.len(), ctx.lower_ty(&data.type_ref))
1040} 1050}
1041 1051
1042/// Build the declared type of a static. 1052/// Build the declared type of a static.
@@ -1045,7 +1055,7 @@ fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
1045 let resolver = def.resolver(db.upcast()); 1055 let resolver = def.resolver(db.upcast());
1046 let ctx = TyLoweringContext::new(db, &resolver); 1056 let ctx = TyLoweringContext::new(db, &resolver);
1047 1057
1048 Binders::new(0, Ty::from_hir(&ctx, &data.type_ref)) 1058 Binders::new(0, ctx.lower_ty(&data.type_ref))
1049} 1059}
1050 1060
1051fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig { 1061fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
@@ -1054,8 +1064,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
1054 let resolver = def.resolver(db.upcast()); 1064 let resolver = def.resolver(db.upcast());
1055 let ctx = 1065 let ctx =
1056 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1066 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1057 let params = 1067 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1058 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
1059 let ret = type_for_adt(db, def.into()); 1068 let ret = type_for_adt(db, def.into());
1060 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) 1069 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
1061} 1070}
@@ -1068,7 +1077,10 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
1068 } 1077 }
1069 let generics = generics(db.upcast(), def.into()); 1078 let generics = generics(db.upcast(), def.into());
1070 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1079 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1071 Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) 1080 Binders::new(
1081 substs.len(),
1082 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner),
1083 )
1072} 1084}
1073 1085
1074fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { 1086fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
@@ -1078,8 +1090,7 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
1078 let resolver = def.parent.resolver(db.upcast()); 1090 let resolver = def.parent.resolver(db.upcast());
1079 let ctx = 1091 let ctx =
1080 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1092 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1081 let params = 1093 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1082 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
1083 let ret = type_for_adt(db, def.parent.into()); 1094 let ret = type_for_adt(db, def.parent.into());
1084 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) 1095 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
1085} 1096}
@@ -1093,7 +1104,10 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1093 } 1104 }
1094 let generics = generics(db.upcast(), def.parent.into()); 1105 let generics = generics(db.upcast(), def.parent.into());
1095 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1106 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1096 Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) 1107 Binders::new(
1108 substs.len(),
1109 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner),
1110 )
1097} 1111}
1098 1112
1099fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { 1113fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
@@ -1108,11 +1122,11 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1108 let ctx = 1122 let ctx =
1109 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1123 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1110 if db.type_alias_data(t).is_extern { 1124 if db.type_alias_data(t).is_extern {
1111 Binders::new(0, Ty::ForeignType(t)) 1125 Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner))
1112 } else { 1126 } else {
1113 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1127 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1114 let type_ref = &db.type_alias_data(t).type_ref; 1128 let type_ref = &db.type_alias_data(t).type_ref;
1115 let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error)); 1129 let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error));
1116 Binders::new(substs.len(), inner) 1130 Binders::new(substs.len(), inner)
1117 } 1131 }
1118} 1132}
@@ -1184,7 +1198,7 @@ pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId)
1184 TyDefId::AdtId(it) => generics(db.upcast(), it.into()).len(), 1198 TyDefId::AdtId(it) => generics(db.upcast(), it.into()).len(),
1185 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()).len(), 1199 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()).len(),
1186 }; 1200 };
1187 Binders::new(num_binders, Ty::Unknown) 1201 Binders::new(num_binders, TyKind::Unknown.intern(&Interner))
1188} 1202}
1189 1203
1190pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> { 1204pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
@@ -1204,7 +1218,7 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde
1204 let generics = generics(db.upcast(), impl_id.into()); 1218 let generics = generics(db.upcast(), impl_id.into());
1205 let ctx = 1219 let ctx =
1206 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1220 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1207 Binders::new(generics.len(), Ty::from_hir(&ctx, &impl_data.target_type)) 1221 Binders::new(generics.len(), ctx.lower_ty(&impl_data.target_type))
1208} 1222}
1209 1223
1210pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { 1224pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
@@ -1213,7 +1227,7 @@ pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> T
1213 let resolver = def.parent.resolver(db.upcast()); 1227 let resolver = def.parent.resolver(db.upcast());
1214 let ctx = TyLoweringContext::new(db, &resolver); 1228 let ctx = TyLoweringContext::new(db, &resolver);
1215 1229
1216 Ty::from_hir(&ctx, &data.ty) 1230 ctx.lower_ty(&data.ty)
1217} 1231}
1218 1232
1219pub(crate) fn impl_self_ty_recover( 1233pub(crate) fn impl_self_ty_recover(
@@ -1222,7 +1236,7 @@ pub(crate) fn impl_self_ty_recover(
1222 impl_id: &ImplId, 1236 impl_id: &ImplId,
1223) -> Binders<Ty> { 1237) -> Binders<Ty> {
1224 let generics = generics(db.upcast(), (*impl_id).into()); 1238 let generics = generics(db.upcast(), (*impl_id).into());
1225 Binders::new(generics.len(), Ty::Unknown) 1239 Binders::new(generics.len(), TyKind::Unknown.intern(&Interner))
1226} 1240}
1227 1241
1228pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { 1242pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
@@ -1232,10 +1246,7 @@ pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<
1232 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1246 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1233 let self_ty = db.impl_self_ty(impl_id); 1247 let self_ty = db.impl_self_ty(impl_id);
1234 let target_trait = impl_data.target_trait.as_ref()?; 1248 let target_trait = impl_data.target_trait.as_ref()?;
1235 Some(Binders::new( 1249 Some(Binders::new(self_ty.num_binders, ctx.lower_trait_ref(target_trait, Some(self_ty.value))?))
1236 self_ty.num_binders,
1237 TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value))?,
1238 ))
1239} 1250}
1240 1251
1241pub(crate) fn return_type_impl_traits( 1252pub(crate) fn return_type_impl_traits(
@@ -1248,7 +1259,7 @@ pub(crate) fn return_type_impl_traits(
1248 let ctx_ret = TyLoweringContext::new(db, &resolver) 1259 let ctx_ret = TyLoweringContext::new(db, &resolver)
1249 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) 1260 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1250 .with_type_param_mode(TypeParamLoweringMode::Variable); 1261 .with_type_param_mode(TypeParamLoweringMode::Variable);
1251 let _ret = Ty::from_hir(&ctx_ret, &data.ret_type); 1262 let _ret = (&ctx_ret).lower_ty(&data.ret_type);
1252 let generics = generics(db.upcast(), def.into()); 1263 let generics = generics(db.upcast(), def.into());
1253 let num_binders = generics.len(); 1264 let num_binders = generics.len();
1254 let return_type_impl_traits = 1265 let return_type_impl_traits =