]> git.lizzy.rs Git - rust.git/blob - crates/hir-ty/src/lower.rs
feat: support negative const generic parameters
[rust.git] / crates / hir-ty / src / lower.rs
1 //! Methods for lowering the HIR to types. There are two main cases here:
2 //!
3 //!  - Lowering a type reference like `&usize` or `Option<foo::bar::Baz>` to a
4 //!    type: The entry point for this is `Ty::from_hir`.
5 //!  - Building the type for an item: This happens through the `type_for_def` query.
6 //!
7 //! This usually involves resolving names, collecting generic arguments etc.
8 use std::{
9     cell::{Cell, RefCell},
10     iter,
11     sync::Arc,
12 };
13
14 use base_db::CrateId;
15 use chalk_ir::{
16     cast::Cast, fold::Shift, fold::TypeFoldable, interner::HasInterner, Mutability, Safety,
17 };
18
19 use hir_def::{
20     adt::StructKind,
21     body::{Expander, LowerCtx},
22     builtin_type::BuiltinType,
23     generics::{
24         TypeOrConstParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
25     },
26     intern::Interned,
27     lang_item::lang_attr,
28     path::{GenericArg, ModPath, Path, PathKind, PathSegment, PathSegments},
29     resolver::{HasResolver, Resolver, TypeNs},
30     type_ref::{
31         ConstScalarOrPath, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef,
32     },
33     AdtId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId,
34     HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
35     TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, VariantId,
36 };
37 use hir_expand::{name::Name, ExpandResult};
38 use itertools::Either;
39 use la_arena::ArenaMap;
40 use rustc_hash::FxHashSet;
41 use smallvec::SmallVec;
42 use stdx::{impl_from, never};
43 use syntax::{ast, SmolStr};
44
45 use crate::{
46     all_super_traits,
47     consteval::{
48         intern_const_scalar_with_type, path_to_const, unknown_const, unknown_const_as_generic,
49     },
50     db::HirDatabase,
51     make_binders,
52     mapping::ToChalk,
53     static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
54     utils::Generics,
55     utils::{all_super_trait_refs, associated_type_by_name_including_super_traits, generics},
56     AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, DebruijnIndex, DynTy, FnPointer,
57     FnSig, FnSubst, GenericArgData, ImplTraitId, Interner, ParamKind, PolyFnSig, ProjectionTy,
58     QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits,
59     Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
60 };
61
62 #[derive(Debug)]
63 pub struct TyLoweringContext<'a> {
64     pub db: &'a dyn HirDatabase,
65     pub resolver: &'a Resolver,
66     in_binders: DebruijnIndex,
67     /// Note: Conceptually, it's thinkable that we could be in a location where
68     /// some type params should be represented as placeholders, and others
69     /// should be converted to variables. I think in practice, this isn't
70     /// possible currently, so this should be fine for now.
71     pub type_param_mode: ParamLoweringMode,
72     pub impl_trait_mode: ImplTraitLoweringMode,
73     impl_trait_counter: Cell<u16>,
74     /// When turning `impl Trait` into opaque types, we have to collect the
75     /// bounds at the same time to get the IDs correct (without becoming too
76     /// complicated). I don't like using interior mutability (as for the
77     /// counter), but I've tried and failed to make the lifetimes work for
78     /// passing around a `&mut TyLoweringContext`. The core problem is that
79     /// we're grouping the mutable data (the counter and this field) together
80     /// with the immutable context (the references to the DB and resolver).
81     /// Splitting this up would be a possible fix.
82     opaque_type_data: RefCell<Vec<ReturnTypeImplTrait>>,
83     expander: RefCell<Option<Expander>>,
84     /// Tracks types with explicit `?Sized` bounds.
85     pub(crate) unsized_types: RefCell<FxHashSet<Ty>>,
86 }
87
88 impl<'a> TyLoweringContext<'a> {
89     pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver) -> Self {
90         let impl_trait_counter = Cell::new(0);
91         let impl_trait_mode = ImplTraitLoweringMode::Disallowed;
92         let type_param_mode = ParamLoweringMode::Placeholder;
93         let in_binders = DebruijnIndex::INNERMOST;
94         let opaque_type_data = RefCell::new(Vec::new());
95         Self {
96             db,
97             resolver,
98             in_binders,
99             impl_trait_mode,
100             impl_trait_counter,
101             type_param_mode,
102             opaque_type_data,
103             expander: RefCell::new(None),
104             unsized_types: RefCell::default(),
105         }
106     }
107
108     pub fn with_debruijn<T>(
109         &self,
110         debruijn: DebruijnIndex,
111         f: impl FnOnce(&TyLoweringContext) -> T,
112     ) -> T {
113         let opaque_ty_data_vec = self.opaque_type_data.take();
114         let expander = self.expander.take();
115         let unsized_types = self.unsized_types.take();
116         let new_ctx = Self {
117             in_binders: debruijn,
118             impl_trait_counter: Cell::new(self.impl_trait_counter.get()),
119             opaque_type_data: RefCell::new(opaque_ty_data_vec),
120             expander: RefCell::new(expander),
121             unsized_types: RefCell::new(unsized_types),
122             ..*self
123         };
124         let result = f(&new_ctx);
125         self.impl_trait_counter.set(new_ctx.impl_trait_counter.get());
126         self.opaque_type_data.replace(new_ctx.opaque_type_data.into_inner());
127         self.expander.replace(new_ctx.expander.into_inner());
128         self.unsized_types.replace(new_ctx.unsized_types.into_inner());
129         result
130     }
131
132     pub fn with_shifted_in<T>(
133         &self,
134         debruijn: DebruijnIndex,
135         f: impl FnOnce(&TyLoweringContext) -> T,
136     ) -> T {
137         self.with_debruijn(self.in_binders.shifted_in_from(debruijn), f)
138     }
139
140     pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
141         Self { impl_trait_mode, ..self }
142     }
143
144     pub fn with_type_param_mode(self, type_param_mode: ParamLoweringMode) -> Self {
145         Self { type_param_mode, ..self }
146     }
147 }
148
149 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
150 pub enum ImplTraitLoweringMode {
151     /// `impl Trait` gets lowered into an opaque type that doesn't unify with
152     /// anything except itself. This is used in places where values flow 'out',
153     /// i.e. for arguments of the function we're currently checking, and return
154     /// types of functions we're calling.
155     Opaque,
156     /// `impl Trait` gets lowered into a type variable. Used for argument
157     /// position impl Trait when inside the respective function, since it allows
158     /// us to support that without Chalk.
159     Param,
160     /// `impl Trait` gets lowered into a variable that can unify with some
161     /// type. This is used in places where values flow 'in', i.e. for arguments
162     /// of functions we're calling, and the return type of the function we're
163     /// currently checking.
164     Variable,
165     /// `impl Trait` is disallowed and will be an error.
166     Disallowed,
167 }
168
169 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
170 pub enum ParamLoweringMode {
171     Placeholder,
172     Variable,
173 }
174
175 impl<'a> TyLoweringContext<'a> {
176     pub fn lower_ty(&self, type_ref: &TypeRef) -> Ty {
177         self.lower_ty_ext(type_ref).0
178     }
179
180     fn generics(&self) -> Generics {
181         generics(
182             self.db.upcast(),
183             self.resolver
184                 .generic_def()
185                 .expect("there should be generics if there's a generic param"),
186         )
187     }
188
189     pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
190         let mut res = None;
191         let ty = match type_ref {
192             TypeRef::Never => TyKind::Never.intern(Interner),
193             TypeRef::Tuple(inner) => {
194                 let inner_tys = inner.iter().map(|tr| self.lower_ty(tr));
195                 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(Interner, inner_tys))
196                     .intern(Interner)
197             }
198             TypeRef::Path(path) => {
199                 let (ty, res_) = self.lower_path(path);
200                 res = res_;
201                 ty
202             }
203             TypeRef::RawPtr(inner, mutability) => {
204                 let inner_ty = self.lower_ty(inner);
205                 TyKind::Raw(lower_to_chalk_mutability(*mutability), inner_ty).intern(Interner)
206             }
207             TypeRef::Array(inner, len) => {
208                 let inner_ty = self.lower_ty(inner);
209                 let const_len = const_or_path_to_chalk(
210                     self.db,
211                     self.resolver,
212                     TyBuilder::usize(),
213                     len,
214                     self.type_param_mode,
215                     || self.generics(),
216                     self.in_binders,
217                 );
218
219                 TyKind::Array(inner_ty, const_len).intern(Interner)
220             }
221             TypeRef::Slice(inner) => {
222                 let inner_ty = self.lower_ty(inner);
223                 TyKind::Slice(inner_ty).intern(Interner)
224             }
225             TypeRef::Reference(inner, _, mutability) => {
226                 let inner_ty = self.lower_ty(inner);
227                 let lifetime = static_lifetime();
228                 TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty)
229                     .intern(Interner)
230             }
231             TypeRef::Placeholder => TyKind::Error.intern(Interner),
232             TypeRef::Fn(params, is_varargs) => {
233                 let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
234                     Substitution::from_iter(Interner, params.iter().map(|(_, tr)| ctx.lower_ty(tr)))
235                 });
236                 TyKind::Function(FnPointer {
237                     num_binders: 0, // FIXME lower `for<'a> fn()` correctly
238                     sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
239                     substitution: FnSubst(substs),
240                 })
241                 .intern(Interner)
242             }
243             TypeRef::DynTrait(bounds) => {
244                 let self_ty =
245                     TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
246                 let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
247                     QuantifiedWhereClauses::from_iter(
248                         Interner,
249                         bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
250                     )
251                 });
252                 let bounds = crate::make_single_type_binders(bounds);
253                 TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
254             }
255             TypeRef::ImplTrait(bounds) => {
256                 match self.impl_trait_mode {
257                     ImplTraitLoweringMode::Opaque => {
258                         let idx = self.impl_trait_counter.get();
259                         self.impl_trait_counter.set(idx + 1);
260                         let func = match self.resolver.generic_def() {
261                             Some(GenericDefId::FunctionId(f)) => f,
262                             _ => panic!("opaque impl trait lowering in non-function"),
263                         };
264
265                         assert!(idx as usize == self.opaque_type_data.borrow().len());
266                         // this dance is to make sure the data is in the right
267                         // place even if we encounter more opaque types while
268                         // lowering the bounds
269                         self.opaque_type_data.borrow_mut().push(ReturnTypeImplTrait {
270                             bounds: crate::make_single_type_binders(Vec::new()),
271                         });
272                         // We don't want to lower the bounds inside the binders
273                         // we're currently in, because they don't end up inside
274                         // those binders. E.g. when we have `impl Trait<impl
275                         // OtherTrait<T>>`, the `impl OtherTrait<T>` can't refer
276                         // to the self parameter from `impl Trait`, and the
277                         // bounds aren't actually stored nested within each
278                         // other, but separately. So if the `T` refers to a type
279                         // parameter of the outer function, it's just one binder
280                         // away instead of two.
281                         let actual_opaque_type_data = self
282                             .with_debruijn(DebruijnIndex::INNERMOST, |ctx| {
283                                 ctx.lower_impl_trait(bounds, func)
284                             });
285                         self.opaque_type_data.borrow_mut()[idx as usize] = actual_opaque_type_data;
286
287                         let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx);
288                         let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
289                         let generics = generics(self.db.upcast(), func.into());
290                         let parameters = generics.bound_vars_subst(self.db, self.in_binders);
291                         TyKind::OpaqueType(opaque_ty_id, parameters).intern(Interner)
292                     }
293                     ImplTraitLoweringMode::Param => {
294                         let idx = self.impl_trait_counter.get();
295                         // FIXME we're probably doing something wrong here
296                         self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
297                         if let Some(def) = self.resolver.generic_def() {
298                             let generics = generics(self.db.upcast(), def);
299                             let param = generics
300                                 .iter()
301                                 .filter(|(_, data)| {
302                                     matches!(
303                                         data,
304                                         TypeOrConstParamData::TypeParamData(data)
305                                         if data.provenance == TypeParamProvenance::ArgumentImplTrait
306                                     )
307                                 })
308                                 .nth(idx as usize)
309                                 .map_or(TyKind::Error, |(id, _)| {
310                                     TyKind::Placeholder(to_placeholder_idx(self.db, id))
311                                 });
312                             param.intern(Interner)
313                         } else {
314                             TyKind::Error.intern(Interner)
315                         }
316                     }
317                     ImplTraitLoweringMode::Variable => {
318                         let idx = self.impl_trait_counter.get();
319                         // FIXME we're probably doing something wrong here
320                         self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
321                         let (
322                             parent_params,
323                             self_params,
324                             list_params,
325                             const_params,
326                             _impl_trait_params,
327                         ) = if let Some(def) = self.resolver.generic_def() {
328                             let generics = generics(self.db.upcast(), def);
329                             generics.provenance_split()
330                         } else {
331                             (0, 0, 0, 0, 0)
332                         };
333                         TyKind::BoundVar(BoundVar::new(
334                             self.in_binders,
335                             idx as usize + parent_params + self_params + list_params + const_params,
336                         ))
337                         .intern(Interner)
338                     }
339                     ImplTraitLoweringMode::Disallowed => {
340                         // FIXME: report error
341                         TyKind::Error.intern(Interner)
342                     }
343                 }
344             }
345             TypeRef::Macro(macro_call) => {
346                 let (expander, recursion_start) = {
347                     let mut expander = self.expander.borrow_mut();
348                     if expander.is_some() {
349                         (Some(expander), false)
350                     } else {
351                         *expander = Some(Expander::new(
352                             self.db.upcast(),
353                             macro_call.file_id,
354                             self.resolver.module(),
355                         ));
356                         (Some(expander), true)
357                     }
358                 };
359                 let ty = if let Some(mut expander) = expander {
360                     let expander_mut = expander.as_mut().unwrap();
361                     let macro_call = macro_call.to_node(self.db.upcast());
362                     match expander_mut.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
363                         Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
364                             let ctx =
365                                 LowerCtx::new(self.db.upcast(), expander_mut.current_file_id());
366                             let type_ref = TypeRef::from_ast(&ctx, expanded);
367
368                             drop(expander);
369                             let ty = self.lower_ty(&type_ref);
370
371                             self.expander
372                                 .borrow_mut()
373                                 .as_mut()
374                                 .unwrap()
375                                 .exit(self.db.upcast(), mark);
376                             Some(ty)
377                         }
378                         _ => None,
379                     }
380                 } else {
381                     None
382                 };
383                 if recursion_start {
384                     *self.expander.borrow_mut() = None;
385                 }
386                 ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
387             }
388             TypeRef::Error => TyKind::Error.intern(Interner),
389         };
390         (ty, res)
391     }
392
393     /// This is only for `generic_predicates_for_param`, where we can't just
394     /// lower the self types of the predicates since that could lead to cycles.
395     /// So we just check here if the `type_ref` resolves to a generic param, and which.
396     fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeOrConstParamId> {
397         let path = match type_ref {
398             TypeRef::Path(path) => path,
399             _ => return None,
400         };
401         if path.type_anchor().is_some() {
402             return None;
403         }
404         if path.segments().len() > 1 {
405             return None;
406         }
407         let resolution =
408             match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
409                 Some((it, None)) => it,
410                 _ => return None,
411             };
412         match resolution {
413             TypeNs::GenericParam(param_id) => Some(param_id.into()),
414             _ => None,
415         }
416     }
417
418     pub(crate) fn lower_ty_relative_path(
419         &self,
420         ty: Ty,
421         // We need the original resolution to lower `Self::AssocTy` correctly
422         res: Option<TypeNs>,
423         remaining_segments: PathSegments<'_>,
424     ) -> (Ty, Option<TypeNs>) {
425         match remaining_segments.len() {
426             0 => (ty, res),
427             1 => {
428                 // resolve unselected assoc types
429                 let segment = remaining_segments.first().unwrap();
430                 (self.select_associated_type(res, segment), None)
431             }
432             _ => {
433                 // FIXME report error (ambiguous associated type)
434                 (TyKind::Error.intern(Interner), None)
435             }
436         }
437     }
438
439     pub(crate) fn lower_partly_resolved_path(
440         &self,
441         resolution: TypeNs,
442         resolved_segment: PathSegment<'_>,
443         remaining_segments: PathSegments<'_>,
444         infer_args: bool,
445     ) -> (Ty, Option<TypeNs>) {
446         let ty = match resolution {
447             TypeNs::TraitId(trait_) => {
448                 let ty = match remaining_segments.len() {
449                     1 => {
450                         let trait_ref =
451                             self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None);
452                         let segment = remaining_segments.first().unwrap();
453                         let found = self
454                             .db
455                             .trait_data(trait_ref.hir_trait_id())
456                             .associated_type_by_name(segment.name);
457                         match found {
458                             Some(associated_ty) => {
459                                 // FIXME handle type parameters on the segment
460                                 TyKind::Alias(AliasTy::Projection(ProjectionTy {
461                                     associated_ty_id: to_assoc_type_id(associated_ty),
462                                     substitution: trait_ref.substitution,
463                                 }))
464                                 .intern(Interner)
465                             }
466                             None => {
467                                 // FIXME: report error (associated type not found)
468                                 TyKind::Error.intern(Interner)
469                             }
470                         }
471                     }
472                     0 => {
473                         let self_ty = Some(
474                             TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
475                                 .intern(Interner),
476                         );
477                         let trait_ref = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
478                             ctx.lower_trait_ref_from_resolved_path(
479                                 trait_,
480                                 resolved_segment,
481                                 self_ty,
482                             )
483                         });
484                         let dyn_ty = DynTy {
485                             bounds: crate::make_single_type_binders(
486                                 QuantifiedWhereClauses::from_iter(
487                                     Interner,
488                                     Some(crate::wrap_empty_binders(WhereClause::Implemented(
489                                         trait_ref,
490                                     ))),
491                                 ),
492                             ),
493                             lifetime: static_lifetime(),
494                         };
495                         TyKind::Dyn(dyn_ty).intern(Interner)
496                     }
497                     _ => {
498                         // FIXME report error (ambiguous associated type)
499                         TyKind::Error.intern(Interner)
500                     }
501                 };
502                 return (ty, None);
503             }
504             TypeNs::GenericParam(param_id) => {
505                 let generics = generics(
506                     self.db.upcast(),
507                     self.resolver.generic_def().expect("generics in scope"),
508                 );
509                 match self.type_param_mode {
510                     ParamLoweringMode::Placeholder => {
511                         TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into()))
512                     }
513                     ParamLoweringMode::Variable => {
514                         let idx = generics.param_idx(param_id.into()).expect("matching generics");
515                         TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
516                     }
517                 }
518                 .intern(Interner)
519             }
520             TypeNs::SelfType(impl_id) => {
521                 let generics = generics(self.db.upcast(), impl_id.into());
522                 let substs = match self.type_param_mode {
523                     ParamLoweringMode::Placeholder => generics.placeholder_subst(self.db),
524                     ParamLoweringMode::Variable => {
525                         generics.bound_vars_subst(self.db, self.in_binders)
526                     }
527                 };
528                 self.db.impl_self_ty(impl_id).substitute(Interner, &substs)
529             }
530             TypeNs::AdtSelfType(adt) => {
531                 let generics = generics(self.db.upcast(), adt.into());
532                 let substs = match self.type_param_mode {
533                     ParamLoweringMode::Placeholder => generics.placeholder_subst(self.db),
534                     ParamLoweringMode::Variable => {
535                         generics.bound_vars_subst(self.db, self.in_binders)
536                     }
537                 };
538                 self.db.ty(adt.into()).substitute(Interner, &substs)
539             }
540
541             TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args),
542             TypeNs::BuiltinType(it) => {
543                 self.lower_path_inner(resolved_segment, it.into(), infer_args)
544             }
545             TypeNs::TypeAliasId(it) => {
546                 self.lower_path_inner(resolved_segment, it.into(), infer_args)
547             }
548             // FIXME: report error
549             TypeNs::EnumVariantId(_) => return (TyKind::Error.intern(Interner), None),
550         };
551         self.lower_ty_relative_path(ty, Some(resolution), remaining_segments)
552     }
553
554     pub(crate) fn lower_path(&self, path: &Path) -> (Ty, Option<TypeNs>) {
555         // Resolve the path (in type namespace)
556         if let Some(type_ref) = path.type_anchor() {
557             let (ty, res) = self.lower_ty_ext(type_ref);
558             return self.lower_ty_relative_path(ty, res, path.segments());
559         }
560         let (resolution, remaining_index) =
561             match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
562                 Some(it) => it,
563                 None => return (TyKind::Error.intern(Interner), None),
564             };
565         let (resolved_segment, remaining_segments) = match remaining_index {
566             None => (
567                 path.segments().last().expect("resolved path has at least one element"),
568                 PathSegments::EMPTY,
569             ),
570             Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)),
571         };
572         self.lower_partly_resolved_path(resolution, resolved_segment, remaining_segments, false)
573     }
574
575     fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
576         let (def, res) = match (self.resolver.generic_def(), res) {
577             (Some(def), Some(res)) => (def, res),
578             _ => return TyKind::Error.intern(Interner),
579         };
580         let ty = named_associated_type_shorthand_candidates(
581             self.db,
582             def,
583             res,
584             Some(segment.name.clone()),
585             move |name, t, associated_ty| {
586                 if name == segment.name {
587                     let substs = match self.type_param_mode {
588                         ParamLoweringMode::Placeholder => {
589                             // if we're lowering to placeholders, we have to put
590                             // them in now
591                             let generics = generics(
592                                 self.db.upcast(),
593                                 self.resolver
594                                     .generic_def()
595                                     .expect("there should be generics if there's a generic param"),
596                             );
597                             let s = generics.placeholder_subst(self.db);
598                             s.apply(t.substitution.clone(), Interner)
599                         }
600                         ParamLoweringMode::Variable => t.substitution.clone(),
601                     };
602                     // We need to shift in the bound vars, since
603                     // associated_type_shorthand_candidates does not do that
604                     let substs = substs.shifted_in_from(Interner, self.in_binders);
605                     // FIXME handle type parameters on the segment
606                     Some(
607                         TyKind::Alias(AliasTy::Projection(ProjectionTy {
608                             associated_ty_id: to_assoc_type_id(associated_ty),
609                             substitution: substs,
610                         }))
611                         .intern(Interner),
612                     )
613                 } else {
614                     None
615                 }
616             },
617         );
618
619         ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
620     }
621
622     fn lower_path_inner(
623         &self,
624         segment: PathSegment<'_>,
625         typeable: TyDefId,
626         infer_args: bool,
627     ) -> Ty {
628         let generic_def = match typeable {
629             TyDefId::BuiltinType(_) => None,
630             TyDefId::AdtId(it) => Some(it.into()),
631             TyDefId::TypeAliasId(it) => Some(it.into()),
632         };
633         let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None);
634         self.db.ty(typeable).substitute(Interner, &substs)
635     }
636
637     /// Collect generic arguments from a path into a `Substs`. See also
638     /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
639     pub(super) fn substs_from_path(
640         &self,
641         path: &Path,
642         // Note that we don't call `db.value_type(resolved)` here,
643         // `ValueTyDefId` is just a convenient way to pass generics and
644         // special-case enum variants
645         resolved: ValueTyDefId,
646         infer_args: bool,
647     ) -> Substitution {
648         let last = path.segments().last().expect("path should have at least one segment");
649         let (segment, generic_def) = match resolved {
650             ValueTyDefId::FunctionId(it) => (last, Some(it.into())),
651             ValueTyDefId::StructId(it) => (last, Some(it.into())),
652             ValueTyDefId::UnionId(it) => (last, Some(it.into())),
653             ValueTyDefId::ConstId(it) => (last, Some(it.into())),
654             ValueTyDefId::StaticId(_) => (last, None),
655             ValueTyDefId::EnumVariantId(var) => {
656                 // the generic args for an enum variant may be either specified
657                 // on the segment referring to the enum, or on the segment
658                 // referring to the variant. So `Option::<T>::None` and
659                 // `Option::None::<T>` are both allowed (though the former is
660                 // preferred). See also `def_ids_for_path_segments` in rustc.
661                 let len = path.segments().len();
662                 let penultimate = len.checked_sub(2).and_then(|idx| path.segments().get(idx));
663                 let segment = match penultimate {
664                     Some(segment) if segment.args_and_bindings.is_some() => segment,
665                     _ => last,
666                 };
667                 (segment, Some(var.parent.into()))
668             }
669         };
670         self.substs_from_path_segment(segment, generic_def, infer_args, None)
671     }
672
673     fn substs_from_path_segment(
674         &self,
675         segment: PathSegment<'_>,
676         def_generic: Option<GenericDefId>,
677         infer_args: bool,
678         explicit_self_ty: Option<Ty>,
679     ) -> Substitution {
680         let mut substs = Vec::new();
681         let def_generics = if let Some(def) = def_generic {
682             generics(self.db.upcast(), def)
683         } else {
684             return Substitution::empty(Interner);
685         };
686         let (parent_params, self_params, type_params, const_params, impl_trait_params) =
687             def_generics.provenance_split();
688         let total_len =
689             parent_params + self_params + type_params + const_params + impl_trait_params;
690
691         let ty_error = GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner);
692
693         let mut def_generic_iter = def_generics.iter_id();
694
695         for _ in 0..parent_params {
696             if let Some(eid) = def_generic_iter.next() {
697                 match eid {
698                     Either::Left(_) => substs.push(ty_error.clone()),
699                     Either::Right(x) => {
700                         substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
701                     }
702                 }
703             }
704         }
705
706         let fill_self_params = || {
707             for x in explicit_self_ty
708                 .into_iter()
709                 .map(|x| GenericArgData::Ty(x).intern(Interner))
710                 .chain(iter::repeat(ty_error.clone()))
711                 .take(self_params)
712             {
713                 if let Some(id) = def_generic_iter.next() {
714                     assert!(id.is_left());
715                     substs.push(x);
716                 }
717             }
718         };
719         let mut had_explicit_args = false;
720
721         if let Some(generic_args) = &segment.args_and_bindings {
722             if !generic_args.has_self_type {
723                 fill_self_params();
724             }
725             let expected_num = if generic_args.has_self_type {
726                 self_params + type_params + const_params
727             } else {
728                 type_params + const_params
729             };
730             let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
731             // if args are provided, it should be all of them, but we can't rely on that
732             for arg in generic_args
733                 .args
734                 .iter()
735                 .filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
736                 .skip(skip)
737                 .take(expected_num)
738             {
739                 if let Some(id) = def_generic_iter.next() {
740                     if let Some(x) = generic_arg_to_chalk(
741                         self.db,
742                         id,
743                         arg,
744                         &mut (),
745                         |_, type_ref| self.lower_ty(type_ref),
746                         |_, c, ty| {
747                             const_or_path_to_chalk(
748                                 self.db,
749                                 &self.resolver,
750                                 ty,
751                                 c,
752                                 self.type_param_mode,
753                                 || self.generics(),
754                                 self.in_binders,
755                             )
756                         },
757                     ) {
758                         had_explicit_args = true;
759                         substs.push(x);
760                     } else {
761                         // we just filtered them out
762                         never!("Unexpected lifetime argument");
763                     }
764                 }
765             }
766         } else {
767             fill_self_params();
768         }
769
770         // handle defaults. In expression or pattern path segments without
771         // explicitly specified type arguments, missing type arguments are inferred
772         // (i.e. defaults aren't used).
773         if !infer_args || had_explicit_args {
774             if let Some(def_generic) = def_generic {
775                 let defaults = self.db.generic_defaults(def_generic);
776                 assert_eq!(total_len, defaults.len());
777
778                 for default_ty in defaults.iter().skip(substs.len()) {
779                     // each default can depend on the previous parameters
780                     let substs_so_far = Substitution::from_iter(Interner, substs.clone());
781                     if let Some(_id) = def_generic_iter.next() {
782                         substs.push(default_ty.clone().substitute(Interner, &substs_so_far));
783                     }
784                 }
785             }
786         }
787
788         // add placeholders for args that were not provided
789         // FIXME: emit diagnostics in contexts where this is not allowed
790         for eid in def_generic_iter {
791             match eid {
792                 Either::Left(_) => substs.push(ty_error.clone()),
793                 Either::Right(x) => {
794                     substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
795                 }
796             }
797         }
798         // If this assert fails, it means you pushed into subst but didn't call .next() of def_generic_iter
799         assert_eq!(substs.len(), total_len);
800
801         Substitution::from_iter(Interner, substs)
802     }
803
804     fn lower_trait_ref_from_path(
805         &self,
806         path: &Path,
807         explicit_self_ty: Option<Ty>,
808     ) -> Option<TraitRef> {
809         let resolved =
810             match self.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), path.mod_path())? {
811                 TypeNs::TraitId(tr) => tr,
812                 _ => return None,
813             };
814         let segment = path.segments().last().expect("path should have at least one segment");
815         Some(self.lower_trait_ref_from_resolved_path(resolved, segment, explicit_self_ty))
816     }
817
818     pub(crate) fn lower_trait_ref_from_resolved_path(
819         &self,
820         resolved: TraitId,
821         segment: PathSegment<'_>,
822         explicit_self_ty: Option<Ty>,
823     ) -> TraitRef {
824         let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
825         TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
826     }
827
828     fn lower_trait_ref(
829         &self,
830         trait_ref: &HirTraitRef,
831         explicit_self_ty: Option<Ty>,
832     ) -> Option<TraitRef> {
833         self.lower_trait_ref_from_path(&trait_ref.path, explicit_self_ty)
834     }
835
836     fn trait_ref_substs_from_path(
837         &self,
838         segment: PathSegment<'_>,
839         resolved: TraitId,
840         explicit_self_ty: Option<Ty>,
841     ) -> Substitution {
842         self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
843     }
844
845     pub(crate) fn lower_where_predicate(
846         &'a self,
847         where_predicate: &'a WherePredicate,
848         ignore_bindings: bool,
849     ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
850         match where_predicate {
851             WherePredicate::ForLifetime { target, bound, .. }
852             | WherePredicate::TypeBound { target, bound } => {
853                 let self_ty = match target {
854                     WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
855                     WherePredicateTypeTarget::TypeOrConstParam(param_id) => {
856                         let generic_def = self.resolver.generic_def().expect("generics in scope");
857                         let generics = generics(self.db.upcast(), generic_def);
858                         let param_id = hir_def::TypeOrConstParamId {
859                             parent: generic_def,
860                             local_id: *param_id,
861                         };
862                         let placeholder = to_placeholder_idx(self.db, param_id);
863                         match self.type_param_mode {
864                             ParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder),
865                             ParamLoweringMode::Variable => {
866                                 let idx = generics.param_idx(param_id).expect("matching generics");
867                                 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
868                             }
869                         }
870                         .intern(Interner)
871                     }
872                 };
873                 self.lower_type_bound(bound, self_ty, ignore_bindings)
874                     .collect::<Vec<_>>()
875                     .into_iter()
876             }
877             WherePredicate::Lifetime { .. } => vec![].into_iter(),
878         }
879     }
880
881     pub(crate) fn lower_type_bound(
882         &'a self,
883         bound: &'a TypeBound,
884         self_ty: Ty,
885         ignore_bindings: bool,
886     ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
887         let mut bindings = None;
888         let trait_ref = match bound {
889             TypeBound::Path(path, TraitBoundModifier::None) => {
890                 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
891                 bindings
892                     .clone()
893                     .filter(|tr| {
894                         // ignore `T: Drop` or `T: Destruct` bounds.
895                         // - `T: ~const Drop` has a special meaning in Rust 1.61 that we don't implement.
896                         //   (So ideally, we'd only ignore `~const Drop` here)
897                         // - `Destruct` impls are built-in in 1.62 (current nightlies as of 08-04-2022), so until
898                         //   the builtin impls are supported by Chalk, we ignore them here.
899                         if let Some(lang) = lang_attr(self.db.upcast(), tr.hir_trait_id()) {
900                             if lang == "drop" || lang == "destruct" {
901                                 return false;
902                             }
903                         }
904                         true
905                     })
906                     .map(WhereClause::Implemented)
907                     .map(crate::wrap_empty_binders)
908             }
909             TypeBound::Path(path, TraitBoundModifier::Maybe) => {
910                 let sized_trait = self
911                     .db
912                     .lang_item(self.resolver.krate(), SmolStr::new_inline("sized"))
913                     .and_then(|lang_item| lang_item.as_trait());
914                 // Don't lower associated type bindings as the only possible relaxed trait bound
915                 // `?Sized` has no of them.
916                 // If we got another trait here ignore the bound completely.
917                 let trait_id = self
918                     .lower_trait_ref_from_path(path, Some(self_ty.clone()))
919                     .map(|trait_ref| trait_ref.hir_trait_id());
920                 if trait_id == sized_trait {
921                     self.unsized_types.borrow_mut().insert(self_ty);
922                 }
923                 None
924             }
925             TypeBound::ForLifetime(_, path) => {
926                 // FIXME Don't silently drop the hrtb lifetimes here
927                 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
928                 bindings.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
929             }
930             TypeBound::Lifetime(_) => None,
931             TypeBound::Error => None,
932         };
933         trait_ref.into_iter().chain(
934             bindings
935                 .into_iter()
936                 .filter(move |_| !ignore_bindings)
937                 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)),
938         )
939     }
940
941     fn assoc_type_bindings_from_type_bound(
942         &'a self,
943         bound: &'a TypeBound,
944         trait_ref: TraitRef,
945     ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
946         let last_segment = match bound {
947             TypeBound::Path(path, TraitBoundModifier::None) | TypeBound::ForLifetime(_, path) => {
948                 path.segments().last()
949             }
950             TypeBound::Path(_, TraitBoundModifier::Maybe)
951             | TypeBound::Error
952             | TypeBound::Lifetime(_) => None,
953         };
954         last_segment
955             .into_iter()
956             .filter_map(|segment| segment.args_and_bindings)
957             .flat_map(|args_and_bindings| &args_and_bindings.bindings)
958             .flat_map(move |binding| {
959                 let found = associated_type_by_name_including_super_traits(
960                     self.db,
961                     trait_ref.clone(),
962                     &binding.name,
963                 );
964                 let (super_trait_ref, associated_ty) = match found {
965                     None => return SmallVec::new(),
966                     Some(t) => t,
967                 };
968                 let projection_ty = ProjectionTy {
969                     associated_ty_id: to_assoc_type_id(associated_ty),
970                     substitution: super_trait_ref.substitution,
971                 };
972                 let mut preds: SmallVec<[_; 1]> = SmallVec::with_capacity(
973                     binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
974                 );
975                 if let Some(type_ref) = &binding.type_ref {
976                     let ty = self.lower_ty(type_ref);
977                     let alias_eq =
978                         AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
979                     preds.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
980                 }
981                 for bound in &binding.bounds {
982                     preds.extend(self.lower_type_bound(
983                         bound,
984                         TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(Interner),
985                         false,
986                     ));
987                 }
988                 preds
989             })
990     }
991
992     fn lower_impl_trait(
993         &self,
994         bounds: &[Interned<TypeBound>],
995         func: FunctionId,
996     ) -> ReturnTypeImplTrait {
997         cov_mark::hit!(lower_rpit);
998         let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
999         let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
1000             let mut predicates: Vec<_> = bounds
1001                 .iter()
1002                 .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
1003                 .collect();
1004
1005             if !ctx.unsized_types.borrow().contains(&self_ty) {
1006                 let krate = func.lookup(ctx.db.upcast()).module(ctx.db.upcast()).krate();
1007                 let sized_trait = ctx
1008                     .db
1009                     .lang_item(krate, SmolStr::new_inline("sized"))
1010                     .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1011                 let sized_clause = sized_trait.map(|trait_id| {
1012                     let clause = WhereClause::Implemented(TraitRef {
1013                         trait_id,
1014                         substitution: Substitution::from1(Interner, self_ty.clone()),
1015                     });
1016                     crate::wrap_empty_binders(clause)
1017                 });
1018                 predicates.extend(sized_clause.into_iter());
1019                 predicates.shrink_to_fit();
1020             }
1021             predicates
1022         });
1023         ReturnTypeImplTrait { bounds: crate::make_single_type_binders(predicates) }
1024     }
1025 }
1026
1027 fn count_impl_traits(type_ref: &TypeRef) -> usize {
1028     let mut count = 0;
1029     type_ref.walk(&mut |type_ref| {
1030         if matches!(type_ref, TypeRef::ImplTrait(_)) {
1031             count += 1;
1032         }
1033     });
1034     count
1035 }
1036
1037 /// Build the signature of a callable item (function, struct or enum variant).
1038 pub fn callable_item_sig(db: &dyn HirDatabase, def: CallableDefId) -> PolyFnSig {
1039     match def {
1040         CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f),
1041         CallableDefId::StructId(s) => fn_sig_for_struct_constructor(db, s),
1042         CallableDefId::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e),
1043     }
1044 }
1045
1046 pub fn associated_type_shorthand_candidates<R>(
1047     db: &dyn HirDatabase,
1048     def: GenericDefId,
1049     res: TypeNs,
1050     cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
1051 ) -> Option<R> {
1052     named_associated_type_shorthand_candidates(db, def, res, None, cb)
1053 }
1054
1055 fn named_associated_type_shorthand_candidates<R>(
1056     db: &dyn HirDatabase,
1057     // If the type parameter is defined in an impl and we're in a method, there
1058     // might be additional where clauses to consider
1059     def: GenericDefId,
1060     res: TypeNs,
1061     assoc_name: Option<Name>,
1062     mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
1063 ) -> Option<R> {
1064     let mut search = |t| {
1065         for t in all_super_trait_refs(db, t) {
1066             let data = db.trait_data(t.hir_trait_id());
1067
1068             for (name, assoc_id) in &data.items {
1069                 if let AssocItemId::TypeAliasId(alias) = assoc_id {
1070                     if let Some(result) = cb(name, &t, *alias) {
1071                         return Some(result);
1072                     }
1073                 }
1074             }
1075         }
1076         None
1077     };
1078
1079     match res {
1080         TypeNs::SelfType(impl_id) => search(
1081             // we're _in_ the impl -- the binders get added back later. Correct,
1082             // but it would be nice to make this more explicit
1083             db.impl_trait(impl_id)?.into_value_and_skipped_binders().0,
1084         ),
1085         TypeNs::GenericParam(param_id) => {
1086             let predicates = db.generic_predicates_for_param(def, param_id.into(), assoc_name);
1087             let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
1088                 // FIXME: how to correctly handle higher-ranked bounds here?
1089                 WhereClause::Implemented(tr) => search(
1090                     tr.clone()
1091                         .shifted_out_to(Interner, DebruijnIndex::ONE)
1092                         .expect("FIXME unexpected higher-ranked trait bound"),
1093                 ),
1094                 _ => None,
1095             });
1096             if let Some(_) = res {
1097                 return res;
1098             }
1099             // Handle `Self::Type` referring to own associated type in trait definitions
1100             if let GenericDefId::TraitId(trait_id) = param_id.parent() {
1101                 let generics = generics(db.upcast(), trait_id.into());
1102                 if generics.params.type_or_consts[param_id.local_id()].is_trait_self() {
1103                     let trait_ref = TyBuilder::trait_ref(db, trait_id)
1104                         .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
1105                         .build();
1106                     return search(trait_ref);
1107                 }
1108             }
1109             None
1110         }
1111         _ => None,
1112     }
1113 }
1114
1115 /// Build the type of all specific fields of a struct or enum variant.
1116 pub(crate) fn field_types_query(
1117     db: &dyn HirDatabase,
1118     variant_id: VariantId,
1119 ) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> {
1120     let var_data = variant_id.variant_data(db.upcast());
1121     let (resolver, def): (_, GenericDefId) = match variant_id {
1122         VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()),
1123         VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()),
1124         VariantId::EnumVariantId(it) => (it.parent.resolver(db.upcast()), it.parent.into()),
1125     };
1126     let generics = generics(db.upcast(), def);
1127     let mut res = ArenaMap::default();
1128     let ctx =
1129         TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1130     for (field_id, field_data) in var_data.fields().iter() {
1131         res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref)))
1132     }
1133     Arc::new(res)
1134 }
1135
1136 /// This query exists only to be used when resolving short-hand associated types
1137 /// like `T::Item`.
1138 ///
1139 /// See the analogous query in rustc and its comment:
1140 /// <https://github.com/rust-lang/rust/blob/9150f844e2624eb013ec78ca08c1d416e6644026/src/librustc_typeck/astconv.rs#L46>
1141 /// This is a query mostly to handle cycles somewhat gracefully; e.g. the
1142 /// following bounds are disallowed: `T: Foo<U::Item>, U: Foo<T::Item>`, but
1143 /// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
1144 pub(crate) fn generic_predicates_for_param_query(
1145     db: &dyn HirDatabase,
1146     def: GenericDefId,
1147     param_id: TypeOrConstParamId,
1148     assoc_name: Option<Name>,
1149 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1150     let resolver = def.resolver(db.upcast());
1151     let ctx =
1152         TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1153     let generics = generics(db.upcast(), def);
1154     let mut predicates: Vec<_> = resolver
1155         .where_predicates_in_scope()
1156         // we have to filter out all other predicates *first*, before attempting to lower them
1157         .filter(|pred| match pred {
1158             WherePredicate::ForLifetime { target, bound, .. }
1159             | WherePredicate::TypeBound { target, bound, .. } => {
1160                 match target {
1161                     WherePredicateTypeTarget::TypeRef(type_ref) => {
1162                         if ctx.lower_ty_only_param(type_ref) != Some(param_id) {
1163                             return false;
1164                         }
1165                     }
1166                     WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
1167                         if *local_id != param_id.local_id {
1168                             return false;
1169                         }
1170                     }
1171                 };
1172
1173                 match &**bound {
1174                     TypeBound::ForLifetime(_, path) | TypeBound::Path(path, _) => {
1175                         // Only lower the bound if the trait could possibly define the associated
1176                         // type we're looking for.
1177
1178                         let assoc_name = match &assoc_name {
1179                             Some(it) => it,
1180                             None => return true,
1181                         };
1182                         let tr = match resolver
1183                             .resolve_path_in_type_ns_fully(db.upcast(), path.mod_path())
1184                         {
1185                             Some(TypeNs::TraitId(tr)) => tr,
1186                             _ => return false,
1187                         };
1188
1189                         all_super_traits(db.upcast(), tr).iter().any(|tr| {
1190                             db.trait_data(*tr).items.iter().any(|(name, item)| {
1191                                 matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name
1192                             })
1193                         })
1194                     }
1195                     TypeBound::Lifetime(_) | TypeBound::Error => false,
1196                 }
1197             }
1198             WherePredicate::Lifetime { .. } => false,
1199         })
1200         .flat_map(|pred| {
1201             ctx.lower_where_predicate(pred, true).map(|p| make_binders(db, &generics, p))
1202         })
1203         .collect();
1204
1205     let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1206     let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1207     let implicitly_sized_predicates =
1208         implicitly_sized_clauses(db, param_id.parent, &explicitly_unsized_tys, &subst, &resolver)
1209             .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1210     predicates.extend(implicitly_sized_predicates);
1211     predicates.into()
1212 }
1213
1214 pub(crate) fn generic_predicates_for_param_recover(
1215     _db: &dyn HirDatabase,
1216     _cycle: &[String],
1217     _def: &GenericDefId,
1218     _param_id: &TypeOrConstParamId,
1219     _assoc_name: &Option<Name>,
1220 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1221     Arc::new([])
1222 }
1223
1224 pub(crate) fn trait_environment_query(
1225     db: &dyn HirDatabase,
1226     def: GenericDefId,
1227 ) -> Arc<TraitEnvironment> {
1228     let resolver = def.resolver(db.upcast());
1229     let ctx =
1230         TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Placeholder);
1231     let mut traits_in_scope = Vec::new();
1232     let mut clauses = Vec::new();
1233     for pred in resolver.where_predicates_in_scope() {
1234         for pred in ctx.lower_where_predicate(pred, false) {
1235             if let WhereClause::Implemented(tr) = &pred.skip_binders() {
1236                 traits_in_scope.push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id()));
1237             }
1238             let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1239             clauses.push(program_clause.into_from_env_clause(Interner));
1240         }
1241     }
1242
1243     let container: Option<ItemContainerId> = match def {
1244         // FIXME: is there a function for this?
1245         GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
1246         GenericDefId::AdtId(_) => None,
1247         GenericDefId::TraitId(_) => None,
1248         GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container),
1249         GenericDefId::ImplId(_) => None,
1250         GenericDefId::EnumVariantId(_) => None,
1251         GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container),
1252     };
1253     if let Some(ItemContainerId::TraitId(trait_id)) = container {
1254         // add `Self: Trait<T1, T2, ...>` to the environment in trait
1255         // function default implementations (and speculative code
1256         // inside consts or type aliases)
1257         cov_mark::hit!(trait_self_implements_self);
1258         let substs = TyBuilder::placeholder_subst(db, trait_id);
1259         let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
1260         let pred = WhereClause::Implemented(trait_ref);
1261         let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1262         clauses.push(program_clause.into_from_env_clause(Interner));
1263     }
1264
1265     let subst = generics(db.upcast(), def).placeholder_subst(db);
1266     let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1267     let implicitly_sized_clauses =
1268         implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver).map(|pred| {
1269             let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1270             program_clause.into_from_env_clause(Interner)
1271         });
1272     clauses.extend(implicitly_sized_clauses);
1273
1274     let krate = def.module(db.upcast()).krate();
1275
1276     let env = chalk_ir::Environment::new(Interner).add_clauses(Interner, clauses);
1277
1278     Arc::new(TraitEnvironment { krate, traits_from_clauses: traits_in_scope, env })
1279 }
1280
1281 /// Resolve the where clause(s) of an item with generics.
1282 pub(crate) fn generic_predicates_query(
1283     db: &dyn HirDatabase,
1284     def: GenericDefId,
1285 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1286     let resolver = def.resolver(db.upcast());
1287     let ctx =
1288         TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1289     let generics = generics(db.upcast(), def);
1290
1291     let mut predicates = resolver
1292         .where_predicates_in_scope()
1293         .flat_map(|pred| {
1294             ctx.lower_where_predicate(pred, false).map(|p| make_binders(db, &generics, p))
1295         })
1296         .collect::<Vec<_>>();
1297
1298     let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1299     let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1300     let implicitly_sized_predicates =
1301         implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver)
1302             .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1303     predicates.extend(implicitly_sized_predicates);
1304     predicates.into()
1305 }
1306
1307 /// Generate implicit `: Sized` predicates for all generics that has no `?Sized` bound.
1308 /// Exception is Self of a trait def.
1309 fn implicitly_sized_clauses<'a>(
1310     db: &dyn HirDatabase,
1311     def: GenericDefId,
1312     explicitly_unsized_tys: &'a FxHashSet<Ty>,
1313     substitution: &'a Substitution,
1314     resolver: &Resolver,
1315 ) -> impl Iterator<Item = WhereClause> + 'a {
1316     let is_trait_def = matches!(def, GenericDefId::TraitId(..));
1317     let generic_args = &substitution.as_slice(Interner)[is_trait_def as usize..];
1318     let sized_trait = db
1319         .lang_item(resolver.krate(), SmolStr::new_inline("sized"))
1320         .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1321
1322     sized_trait.into_iter().flat_map(move |sized_trait| {
1323         let implicitly_sized_tys = generic_args
1324             .iter()
1325             .filter_map(|generic_arg| generic_arg.ty(Interner))
1326             .filter(move |&self_ty| !explicitly_unsized_tys.contains(self_ty));
1327         implicitly_sized_tys.map(move |self_ty| {
1328             WhereClause::Implemented(TraitRef {
1329                 trait_id: sized_trait,
1330                 substitution: Substitution::from1(Interner, self_ty.clone()),
1331             })
1332         })
1333     })
1334 }
1335
1336 /// Resolve the default type params from generics
1337 pub(crate) fn generic_defaults_query(
1338     db: &dyn HirDatabase,
1339     def: GenericDefId,
1340 ) -> Arc<[Binders<chalk_ir::GenericArg<Interner>>]> {
1341     let resolver = def.resolver(db.upcast());
1342     let ctx =
1343         TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1344     let generic_params = generics(db.upcast(), def);
1345
1346     let defaults = generic_params
1347         .iter()
1348         .enumerate()
1349         .map(|(idx, (id, p))| {
1350             let p = match p {
1351                 TypeOrConstParamData::TypeParamData(p) => p,
1352                 TypeOrConstParamData::ConstParamData(_) => {
1353                     // FIXME: implement const generic defaults
1354                     let val = unknown_const_as_generic(
1355                         db.const_param_ty(ConstParamId::from_unchecked(id)),
1356                     );
1357                     return crate::make_binders_with_count(db, idx, &generic_params, val);
1358                 }
1359             };
1360             let mut ty =
1361                 p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
1362
1363             // Each default can only refer to previous parameters.
1364             // type variable default referring to parameter coming
1365             // after it. This is forbidden (FIXME: report
1366             // diagnostic)
1367             ty = fallback_bound_vars(ty, idx);
1368             let val = GenericArgData::Ty(ty).intern(Interner);
1369             crate::make_binders_with_count(db, idx, &generic_params, val)
1370         })
1371         .collect();
1372
1373     defaults
1374 }
1375
1376 pub(crate) fn generic_defaults_recover(
1377     db: &dyn HirDatabase,
1378     _cycle: &[String],
1379     def: &GenericDefId,
1380 ) -> Arc<[Binders<crate::GenericArg>]> {
1381     let generic_params = generics(db.upcast(), *def);
1382     // FIXME: this code is not covered in tests.
1383     // we still need one default per parameter
1384     let defaults = generic_params
1385         .iter_id()
1386         .enumerate()
1387         .map(|(count, id)| {
1388             let val = match id {
1389                 itertools::Either::Left(_) => {
1390                     GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1391                 }
1392                 itertools::Either::Right(id) => unknown_const_as_generic(db.const_param_ty(id)),
1393             };
1394             crate::make_binders_with_count(db, count, &generic_params, val)
1395         })
1396         .collect();
1397
1398     defaults
1399 }
1400
1401 fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1402     let data = db.function_data(def);
1403     let resolver = def.resolver(db.upcast());
1404     let ctx_params = TyLoweringContext::new(db, &resolver)
1405         .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
1406         .with_type_param_mode(ParamLoweringMode::Variable);
1407     let params = data.params.iter().map(|(_, tr)| ctx_params.lower_ty(tr)).collect::<Vec<_>>();
1408     let ctx_ret = TyLoweringContext::new(db, &resolver)
1409         .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1410         .with_type_param_mode(ParamLoweringMode::Variable);
1411     let ret = ctx_ret.lower_ty(&data.ret_type);
1412     let generics = generics(db.upcast(), def.into());
1413     let sig = CallableSig::from_params_and_return(params, ret, data.is_varargs());
1414     make_binders(db, &generics, sig)
1415 }
1416
1417 /// Build the declared type of a function. This should not need to look at the
1418 /// function body.
1419 fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1420     let generics = generics(db.upcast(), def.into());
1421     let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1422     make_binders(
1423         db,
1424         &generics,
1425         TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(Interner),
1426     )
1427 }
1428
1429 /// Build the declared type of a const.
1430 fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
1431     let data = db.const_data(def);
1432     let generics = generics(db.upcast(), def.into());
1433     let resolver = def.resolver(db.upcast());
1434     let ctx =
1435         TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1436
1437     make_binders(db, &generics, ctx.lower_ty(&data.type_ref))
1438 }
1439
1440 /// Build the declared type of a static.
1441 fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
1442     let data = db.static_data(def);
1443     let resolver = def.resolver(db.upcast());
1444     let ctx = TyLoweringContext::new(db, &resolver);
1445
1446     Binders::empty(Interner, ctx.lower_ty(&data.type_ref))
1447 }
1448
1449 fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
1450     let struct_data = db.struct_data(def);
1451     let fields = struct_data.variant_data.fields();
1452     let resolver = def.resolver(db.upcast());
1453     let ctx =
1454         TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1455     let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1456     let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
1457     Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1458 }
1459
1460 /// Build the type of a tuple struct constructor.
1461 fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<Ty> {
1462     let struct_data = db.struct_data(def);
1463     if let StructKind::Unit = struct_data.variant_data.kind() {
1464         return type_for_adt(db, def.into());
1465     }
1466     let generics = generics(db.upcast(), def.into());
1467     let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1468     make_binders(
1469         db,
1470         &generics,
1471         TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
1472     )
1473 }
1474
1475 fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
1476     let enum_data = db.enum_data(def.parent);
1477     let var_data = &enum_data.variants[def.local_id];
1478     let fields = var_data.variant_data.fields();
1479     let resolver = def.parent.resolver(db.upcast());
1480     let ctx =
1481         TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1482     let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1483     let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
1484     Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1485 }
1486
1487 /// Build the type of a tuple enum variant constructor.
1488 fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> Binders<Ty> {
1489     let enum_data = db.enum_data(def.parent);
1490     let var_data = &enum_data.variants[def.local_id].variant_data;
1491     if let StructKind::Unit = var_data.kind() {
1492         return type_for_adt(db, def.parent.into());
1493     }
1494     let generics = generics(db.upcast(), def.parent.into());
1495     let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1496     make_binders(
1497         db,
1498         &generics,
1499         TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(Interner),
1500     )
1501 }
1502
1503 fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1504     let generics = generics(db.upcast(), adt.into());
1505     let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1506     let ty = TyKind::Adt(crate::AdtId(adt), subst).intern(Interner);
1507     make_binders(db, &generics, ty)
1508 }
1509
1510 fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1511     let generics = generics(db.upcast(), t.into());
1512     let resolver = t.resolver(db.upcast());
1513     let ctx =
1514         TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1515     if db.type_alias_data(t).is_extern {
1516         Binders::empty(Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner))
1517     } else {
1518         let type_ref = &db.type_alias_data(t).type_ref;
1519         let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
1520         make_binders(db, &generics, inner)
1521     }
1522 }
1523
1524 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1525 pub enum CallableDefId {
1526     FunctionId(FunctionId),
1527     StructId(StructId),
1528     EnumVariantId(EnumVariantId),
1529 }
1530 impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
1531
1532 impl CallableDefId {
1533     pub fn krate(self, db: &dyn HirDatabase) -> CrateId {
1534         let db = db.upcast();
1535         match self {
1536             CallableDefId::FunctionId(f) => f.lookup(db).module(db),
1537             CallableDefId::StructId(s) => s.lookup(db).container,
1538             CallableDefId::EnumVariantId(e) => e.parent.lookup(db).container,
1539         }
1540         .krate()
1541     }
1542 }
1543
1544 impl From<CallableDefId> for GenericDefId {
1545     fn from(def: CallableDefId) -> GenericDefId {
1546         match def {
1547             CallableDefId::FunctionId(f) => f.into(),
1548             CallableDefId::StructId(s) => s.into(),
1549             CallableDefId::EnumVariantId(e) => e.into(),
1550         }
1551     }
1552 }
1553
1554 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1555 pub enum TyDefId {
1556     BuiltinType(BuiltinType),
1557     AdtId(AdtId),
1558     TypeAliasId(TypeAliasId),
1559 }
1560 impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
1561
1562 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1563 pub enum ValueTyDefId {
1564     FunctionId(FunctionId),
1565     StructId(StructId),
1566     UnionId(UnionId),
1567     EnumVariantId(EnumVariantId),
1568     ConstId(ConstId),
1569     StaticId(StaticId),
1570 }
1571 impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
1572
1573 /// Build the declared type of an item. This depends on the namespace; e.g. for
1574 /// `struct Foo(usize)`, we have two types: The type of the struct itself, and
1575 /// the constructor function `(usize) -> Foo` which lives in the values
1576 /// namespace.
1577 pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
1578     match def {
1579         TyDefId::BuiltinType(it) => Binders::empty(Interner, TyBuilder::builtin(it)),
1580         TyDefId::AdtId(it) => type_for_adt(db, it),
1581         TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
1582     }
1583 }
1584
1585 pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> {
1586     let generics = match *def {
1587         TyDefId::BuiltinType(_) => return Binders::empty(Interner, TyKind::Error.intern(Interner)),
1588         TyDefId::AdtId(it) => generics(db.upcast(), it.into()),
1589         TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()),
1590     };
1591     make_binders(db, &generics, TyKind::Error.intern(Interner))
1592 }
1593
1594 pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
1595     match def {
1596         ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
1597         ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
1598         ValueTyDefId::UnionId(it) => type_for_adt(db, it.into()),
1599         ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
1600         ValueTyDefId::ConstId(it) => type_for_const(db, it),
1601         ValueTyDefId::StaticId(it) => type_for_static(db, it),
1602     }
1603 }
1604
1605 pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> {
1606     let impl_loc = impl_id.lookup(db.upcast());
1607     let impl_data = db.impl_data(impl_id);
1608     let resolver = impl_id.resolver(db.upcast());
1609     let _cx = stdx::panic_context::enter(format!(
1610         "impl_self_ty_query({:?} -> {:?} -> {:?})",
1611         impl_id, impl_loc, impl_data
1612     ));
1613     let generics = generics(db.upcast(), impl_id.into());
1614     let ctx =
1615         TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1616     make_binders(db, &generics, ctx.lower_ty(&impl_data.self_ty))
1617 }
1618
1619 // returns None if def is a type arg
1620 pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
1621     let parent_data = db.generic_params(def.parent());
1622     let data = &parent_data.type_or_consts[def.local_id()];
1623     let resolver = def.parent().resolver(db.upcast());
1624     let ctx = TyLoweringContext::new(db, &resolver);
1625     match data {
1626         TypeOrConstParamData::TypeParamData(_) => {
1627             never!();
1628             Ty::new(Interner, TyKind::Error)
1629         }
1630         TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(&d.ty),
1631     }
1632 }
1633
1634 pub(crate) fn impl_self_ty_recover(
1635     db: &dyn HirDatabase,
1636     _cycle: &[String],
1637     impl_id: &ImplId,
1638 ) -> Binders<Ty> {
1639     let generics = generics(db.upcast(), (*impl_id).into());
1640     make_binders(db, &generics, TyKind::Error.intern(Interner))
1641 }
1642
1643 pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
1644     let impl_loc = impl_id.lookup(db.upcast());
1645     let impl_data = db.impl_data(impl_id);
1646     let resolver = impl_id.resolver(db.upcast());
1647     let _cx = stdx::panic_context::enter(format!(
1648         "impl_trait_query({:?} -> {:?} -> {:?})",
1649         impl_id, impl_loc, impl_data
1650     ));
1651     let ctx =
1652         TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1653     let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
1654     let target_trait = impl_data.target_trait.as_ref()?;
1655     Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
1656 }
1657
1658 pub(crate) fn return_type_impl_traits(
1659     db: &dyn HirDatabase,
1660     def: hir_def::FunctionId,
1661 ) -> Option<Arc<Binders<ReturnTypeImplTraits>>> {
1662     // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
1663     let data = db.function_data(def);
1664     let resolver = def.resolver(db.upcast());
1665     let ctx_ret = TyLoweringContext::new(db, &resolver)
1666         .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1667         .with_type_param_mode(ParamLoweringMode::Variable);
1668     let _ret = (&ctx_ret).lower_ty(&data.ret_type);
1669     let generics = generics(db.upcast(), def.into());
1670     let return_type_impl_traits =
1671         ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() };
1672     if return_type_impl_traits.impl_traits.is_empty() {
1673         None
1674     } else {
1675         Some(Arc::new(make_binders(db, &generics, return_type_impl_traits)))
1676     }
1677 }
1678
1679 pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mutability {
1680     match m {
1681         hir_def::type_ref::Mutability::Shared => Mutability::Not,
1682         hir_def::type_ref::Mutability::Mut => Mutability::Mut,
1683     }
1684 }
1685
1686 /// Checks if the provided generic arg matches its expected kind, then lower them via
1687 /// provided closures. Use unknown if there was kind mismatch.
1688 ///
1689 /// Returns `Some` of the lowered generic arg. `None` if the provided arg is a lifetime.
1690 pub(crate) fn generic_arg_to_chalk<'a, T>(
1691     db: &dyn HirDatabase,
1692     kind_id: Either<TypeParamId, ConstParamId>,
1693     arg: &'a GenericArg,
1694     this: &mut T,
1695     for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a,
1696     for_const: impl FnOnce(&mut T, &ConstScalarOrPath, Ty) -> Const + 'a,
1697 ) -> Option<crate::GenericArg> {
1698     let kind = match kind_id {
1699         Either::Left(_) => ParamKind::Type,
1700         Either::Right(id) => {
1701             let ty = db.const_param_ty(id);
1702             ParamKind::Const(ty)
1703         }
1704     };
1705     Some(match (arg, kind) {
1706         (GenericArg::Type(type_ref), ParamKind::Type) => {
1707             let ty = for_type(this, type_ref);
1708             GenericArgData::Ty(ty).intern(Interner)
1709         }
1710         (GenericArg::Const(c), ParamKind::Const(c_ty)) => {
1711             GenericArgData::Const(for_const(this, c, c_ty)).intern(Interner)
1712         }
1713         (GenericArg::Const(_), ParamKind::Type) => {
1714             GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1715         }
1716         (GenericArg::Type(t), ParamKind::Const(c_ty)) => {
1717             // We want to recover simple idents, which parser detects them
1718             // as types. Maybe here is not the best place to do it, but
1719             // it works.
1720             if let TypeRef::Path(p) = t {
1721                 let p = p.mod_path();
1722                 if p.kind == PathKind::Plain {
1723                     if let [n] = p.segments() {
1724                         let c = ConstScalarOrPath::Path(n.clone());
1725                         return Some(
1726                             GenericArgData::Const(for_const(this, &c, c_ty)).intern(Interner),
1727                         );
1728                     }
1729                 }
1730             }
1731             unknown_const_as_generic(c_ty)
1732         }
1733         (GenericArg::Lifetime(_), _) => return None,
1734     })
1735 }
1736
1737 pub(crate) fn const_or_path_to_chalk(
1738     db: &dyn HirDatabase,
1739     resolver: &Resolver,
1740     expected_ty: Ty,
1741     value: &ConstScalarOrPath,
1742     mode: ParamLoweringMode,
1743     args: impl FnOnce() -> Generics,
1744     debruijn: DebruijnIndex,
1745 ) -> Const {
1746     match value {
1747         ConstScalarOrPath::Scalar(s) => intern_const_scalar_with_type(s.clone(), expected_ty),
1748         ConstScalarOrPath::Path(n) => {
1749             let path = ModPath::from_segments(PathKind::Plain, Some(n.clone()));
1750             path_to_const(db, resolver, &path, mode, args, debruijn)
1751                 .unwrap_or_else(|| unknown_const(expected_ty))
1752         }
1753     }
1754 }
1755
1756 /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
1757 /// num_vars_to_keep) by `TyKind::Unknown`.
1758 fn fallback_bound_vars<T: TypeFoldable<Interner> + HasInterner<Interner = Interner>>(
1759     s: T,
1760     num_vars_to_keep: usize,
1761 ) -> T {
1762     crate::fold_free_vars(
1763         s,
1764         |bound, binders| {
1765             if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1766                 TyKind::Error.intern(Interner)
1767             } else {
1768                 bound.shifted_in_from(binders).to_ty(Interner)
1769             }
1770         },
1771         |ty, bound, binders| {
1772             if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1773                 unknown_const(ty.clone())
1774             } else {
1775                 bound.shifted_in_from(binders).to_const(Interner, ty)
1776             }
1777         },
1778     )
1779 }