hir_ty/
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 `TyLoweringContext::lower_ty`.
5//!  - Building the type for an item: This happens through the `ty` query.
6//!
7//! This usually involves resolving names, collecting generic arguments etc.
8pub(crate) mod diagnostics;
9pub(crate) mod path;
10
11use std::{
12    cell::OnceCell,
13    iter, mem,
14    ops::{self, Not as _},
15};
16
17use base_db::Crate;
18use chalk_ir::{
19    Mutability, Safety, TypeOutlives,
20    cast::Cast,
21    fold::{Shift, TypeFoldable},
22    interner::HasInterner,
23};
24
25use either::Either;
26use hir_def::{
27    AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId,
28    FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LocalFieldId,
29    Lookup, StaticId, StructId, TypeAliasId, TypeOrConstParamId, UnionId, VariantId,
30    builtin_type::BuiltinType,
31    expr_store::{ExpressionStore, path::Path},
32    hir::generics::{GenericParamDataRef, TypeOrConstParamData, WherePredicate},
33    item_tree::FieldsShape,
34    lang_item::LangItem,
35    resolver::{HasResolver, LifetimeNs, Resolver, TypeNs},
36    signatures::{FunctionSignature, TraitFlags, TypeAliasFlags},
37    type_ref::{
38        ConstRef, LifetimeRefId, LiteralConstRef, PathId, TraitBoundModifier,
39        TraitRef as HirTraitRef, TypeBound, TypeRef, TypeRefId,
40    },
41};
42use hir_expand::name::Name;
43use la_arena::{Arena, ArenaMap};
44use rustc_hash::FxHashSet;
45use stdx::{impl_from, never};
46use triomphe::{Arc, ThinArc};
47
48use crate::{
49    AliasTy, Binders, BoundVar, CallableSig, Const, DebruijnIndex, DomainGoal, DynTy, FnAbi,
50    FnPointer, FnSig, FnSubst, ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime,
51    LifetimeData, LifetimeOutlives, PolyFnSig, QuantifiedWhereClause, QuantifiedWhereClauses,
52    Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
53    all_super_traits,
54    consteval::{intern_const_ref, path_to_const, unknown_const, unknown_const_as_generic},
55    db::HirDatabase,
56    error_lifetime,
57    generics::{Generics, generics, trait_self_param_idx},
58    lower::{
59        diagnostics::*,
60        path::{PathDiagnosticCallback, PathLoweringContext},
61    },
62    make_binders,
63    mapping::{ToChalk, from_chalk_trait_id, lt_to_placeholder_idx},
64    static_lifetime, to_chalk_trait_id, to_placeholder_idx,
65    utils::all_super_trait_refs,
66    variable_kinds_from_iter,
67};
68
69#[derive(Debug, Default)]
70struct ImplTraitLoweringState {
71    /// When turning `impl Trait` into opaque types, we have to collect the
72    /// bounds at the same time to get the IDs correct (without becoming too
73    /// complicated).
74    mode: ImplTraitLoweringMode,
75    // This is structured as a struct with fields and not as an enum because it helps with the borrow checker.
76    opaque_type_data: Arena<ImplTrait>,
77}
78impl ImplTraitLoweringState {
79    fn new(mode: ImplTraitLoweringMode) -> ImplTraitLoweringState {
80        Self { mode, opaque_type_data: Arena::new() }
81    }
82}
83
84pub(crate) struct PathDiagnosticCallbackData(pub(crate) TypeRefId);
85
86#[derive(Debug, Clone)]
87pub enum LifetimeElisionKind {
88    /// Create a new anonymous lifetime parameter and reference it.
89    ///
90    /// If `report_in_path`, report an error when encountering lifetime elision in a path:
91    /// ```compile_fail
92    /// struct Foo<'a> { x: &'a () }
93    /// async fn foo(x: Foo) {}
94    /// ```
95    ///
96    /// Note: the error should not trigger when the elided lifetime is in a pattern or
97    /// expression-position path:
98    /// ```
99    /// struct Foo<'a> { x: &'a () }
100    /// async fn foo(Foo { x: _ }: Foo<'_>) {}
101    /// ```
102    AnonymousCreateParameter { report_in_path: bool },
103
104    /// Replace all anonymous lifetimes by provided lifetime.
105    Elided(Lifetime),
106
107    /// Give a hard error when either `&` or `'_` is written. Used to
108    /// rule out things like `where T: Foo<'_>`. Does not imply an
109    /// error on default object bounds (e.g., `Box<dyn Foo>`).
110    AnonymousReportError,
111
112    /// Resolves elided lifetimes to `'static` if there are no other lifetimes in scope,
113    /// otherwise give a warning that the previous behavior of introducing a new early-bound
114    /// lifetime is a bug and will be removed (if `only_lint` is enabled).
115    StaticIfNoLifetimeInScope { only_lint: bool },
116
117    /// Signal we cannot find which should be the anonymous lifetime.
118    ElisionFailure,
119
120    /// Infer all elided lifetimes.
121    Infer,
122}
123
124impl LifetimeElisionKind {
125    #[inline]
126    pub(crate) fn for_const(const_parent: ItemContainerId) -> LifetimeElisionKind {
127        match const_parent {
128            ItemContainerId::ExternBlockId(_) | ItemContainerId::ModuleId(_) => {
129                LifetimeElisionKind::Elided(static_lifetime())
130            }
131            ItemContainerId::ImplId(_) => {
132                LifetimeElisionKind::StaticIfNoLifetimeInScope { only_lint: true }
133            }
134            ItemContainerId::TraitId(_) => {
135                LifetimeElisionKind::StaticIfNoLifetimeInScope { only_lint: false }
136            }
137        }
138    }
139
140    #[inline]
141    pub(crate) fn for_fn_params(data: &FunctionSignature) -> LifetimeElisionKind {
142        LifetimeElisionKind::AnonymousCreateParameter { report_in_path: data.is_async() }
143    }
144
145    #[inline]
146    pub(crate) fn for_fn_ret() -> LifetimeElisionKind {
147        // FIXME: We should use the elided lifetime here, or `ElisionFailure`.
148        LifetimeElisionKind::Elided(error_lifetime())
149    }
150}
151
152#[derive(Debug)]
153pub struct TyLoweringContext<'db> {
154    pub db: &'db dyn HirDatabase,
155    resolver: &'db Resolver<'db>,
156    store: &'db ExpressionStore,
157    def: GenericDefId,
158    generics: OnceCell<Generics>,
159    in_binders: DebruijnIndex,
160    /// Note: Conceptually, it's thinkable that we could be in a location where
161    /// some type params should be represented as placeholders, and others
162    /// should be converted to variables. I think in practice, this isn't
163    /// possible currently, so this should be fine for now.
164    pub type_param_mode: ParamLoweringMode,
165    impl_trait_mode: ImplTraitLoweringState,
166    /// Tracks types with explicit `?Sized` bounds.
167    pub(crate) unsized_types: FxHashSet<Ty>,
168    pub(crate) diagnostics: Vec<TyLoweringDiagnostic>,
169    lifetime_elision: LifetimeElisionKind,
170}
171
172impl<'db> TyLoweringContext<'db> {
173    pub fn new(
174        db: &'db dyn HirDatabase,
175        resolver: &'db Resolver<'db>,
176        store: &'db ExpressionStore,
177        def: GenericDefId,
178        lifetime_elision: LifetimeElisionKind,
179    ) -> Self {
180        let impl_trait_mode = ImplTraitLoweringState::new(ImplTraitLoweringMode::Disallowed);
181        let type_param_mode = ParamLoweringMode::Placeholder;
182        let in_binders = DebruijnIndex::INNERMOST;
183        Self {
184            db,
185            resolver,
186            def,
187            generics: Default::default(),
188            store,
189            in_binders,
190            impl_trait_mode,
191            type_param_mode,
192            unsized_types: FxHashSet::default(),
193            diagnostics: Vec::new(),
194            lifetime_elision,
195        }
196    }
197
198    pub fn with_debruijn<T>(
199        &mut self,
200        debruijn: DebruijnIndex,
201        f: impl FnOnce(&mut TyLoweringContext<'_>) -> T,
202    ) -> T {
203        let old_debruijn = mem::replace(&mut self.in_binders, debruijn);
204        let result = f(self);
205        self.in_binders = old_debruijn;
206        result
207    }
208
209    pub fn with_shifted_in<T>(
210        &mut self,
211        debruijn: DebruijnIndex,
212        f: impl FnOnce(&mut TyLoweringContext<'_>) -> T,
213    ) -> T {
214        self.with_debruijn(self.in_binders.shifted_in_from(debruijn), f)
215    }
216
217    fn with_lifetime_elision<T>(
218        &mut self,
219        lifetime_elision: LifetimeElisionKind,
220        f: impl FnOnce(&mut TyLoweringContext<'_>) -> T,
221    ) -> T {
222        let old_lifetime_elision = mem::replace(&mut self.lifetime_elision, lifetime_elision);
223        let result = f(self);
224        self.lifetime_elision = old_lifetime_elision;
225        result
226    }
227
228    pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
229        Self { impl_trait_mode: ImplTraitLoweringState::new(impl_trait_mode), ..self }
230    }
231
232    pub fn with_type_param_mode(self, type_param_mode: ParamLoweringMode) -> Self {
233        Self { type_param_mode, ..self }
234    }
235
236    pub fn impl_trait_mode(&mut self, impl_trait_mode: ImplTraitLoweringMode) -> &mut Self {
237        self.impl_trait_mode = ImplTraitLoweringState::new(impl_trait_mode);
238        self
239    }
240
241    pub fn type_param_mode(&mut self, type_param_mode: ParamLoweringMode) -> &mut Self {
242        self.type_param_mode = type_param_mode;
243        self
244    }
245
246    pub fn push_diagnostic(&mut self, type_ref: TypeRefId, kind: TyLoweringDiagnosticKind) {
247        self.diagnostics.push(TyLoweringDiagnostic { source: type_ref, kind });
248    }
249}
250
251#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
252pub enum ImplTraitLoweringMode {
253    /// `impl Trait` gets lowered into an opaque type that doesn't unify with
254    /// anything except itself. This is used in places where values flow 'out',
255    /// i.e. for arguments of the function we're currently checking, and return
256    /// types of functions we're calling.
257    Opaque,
258    /// `impl Trait` is disallowed and will be an error.
259    #[default]
260    Disallowed,
261}
262
263#[derive(Copy, Clone, Debug, PartialEq, Eq)]
264pub enum ParamLoweringMode {
265    Placeholder,
266    Variable,
267}
268
269impl<'a> TyLoweringContext<'a> {
270    pub fn lower_ty(&mut self, type_ref: TypeRefId) -> Ty {
271        self.lower_ty_ext(type_ref).0
272    }
273
274    pub fn lower_const(&mut self, const_ref: &ConstRef, const_type: Ty) -> Const {
275        let const_ref = &self.store[const_ref.expr];
276        match const_ref {
277            hir_def::hir::Expr::Path(path) => path_to_const(
278                self.db,
279                self.resolver,
280                path,
281                self.type_param_mode,
282                || self.generics(),
283                self.in_binders,
284                const_type.clone(),
285            )
286            .unwrap_or_else(|| unknown_const(const_type)),
287            hir_def::hir::Expr::Literal(literal) => intern_const_ref(
288                self.db,
289                &match *literal {
290                    hir_def::hir::Literal::Float(_, _)
291                    | hir_def::hir::Literal::String(_)
292                    | hir_def::hir::Literal::ByteString(_)
293                    | hir_def::hir::Literal::CString(_) => LiteralConstRef::Unknown,
294                    hir_def::hir::Literal::Char(c) => LiteralConstRef::Char(c),
295                    hir_def::hir::Literal::Bool(b) => LiteralConstRef::Bool(b),
296                    hir_def::hir::Literal::Int(val, _) => LiteralConstRef::Int(val),
297                    hir_def::hir::Literal::Uint(val, _) => LiteralConstRef::UInt(val),
298                },
299                const_type,
300                self.resolver.krate(),
301            ),
302            _ => unknown_const(const_type),
303        }
304    }
305
306    pub fn lower_path_as_const(&mut self, path: &Path, const_type: Ty) -> Const {
307        path_to_const(
308            self.db,
309            self.resolver,
310            path,
311            self.type_param_mode,
312            || self.generics(),
313            self.in_binders,
314            const_type.clone(),
315        )
316        .unwrap_or_else(|| unknown_const(const_type))
317    }
318
319    fn generics(&self) -> &Generics {
320        self.generics.get_or_init(|| generics(self.db, self.def))
321    }
322
323    pub fn lower_ty_ext(&mut self, type_ref_id: TypeRefId) -> (Ty, Option<TypeNs>) {
324        let mut res = None;
325        let type_ref = &self.store[type_ref_id];
326        let ty = match type_ref {
327            TypeRef::Never => TyKind::Never.intern(Interner),
328            TypeRef::Tuple(inner) => {
329                let inner_tys = inner.iter().map(|&tr| self.lower_ty(tr));
330                TyKind::Tuple(inner_tys.len(), Substitution::from_iter(Interner, inner_tys))
331                    .intern(Interner)
332            }
333            TypeRef::Path(path) => {
334                let (ty, res_) =
335                    self.lower_path(path, PathId::from_type_ref_unchecked(type_ref_id));
336                res = res_;
337                ty
338            }
339            &TypeRef::TypeParam(type_param_id) => {
340                res = Some(TypeNs::GenericParam(type_param_id));
341                match self.type_param_mode {
342                    ParamLoweringMode::Placeholder => {
343                        let generics = self.generics();
344                        let idx = generics.type_or_const_param_idx(type_param_id.into()).unwrap();
345                        TyKind::Placeholder(to_placeholder_idx(
346                            self.db,
347                            type_param_id.into(),
348                            idx as u32,
349                        ))
350                    }
351                    ParamLoweringMode::Variable => {
352                        let idx =
353                            self.generics().type_or_const_param_idx(type_param_id.into()).unwrap();
354                        TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
355                    }
356                }
357                .intern(Interner)
358            }
359            &TypeRef::RawPtr(inner, mutability) => {
360                let inner_ty = self.lower_ty(inner);
361                TyKind::Raw(lower_to_chalk_mutability(mutability), inner_ty).intern(Interner)
362            }
363            TypeRef::Array(array) => {
364                let inner_ty = self.lower_ty(array.ty);
365                let const_len = self.lower_const(&array.len, TyBuilder::usize());
366                TyKind::Array(inner_ty, const_len).intern(Interner)
367            }
368            &TypeRef::Slice(inner) => {
369                let inner_ty = self.lower_ty(inner);
370                TyKind::Slice(inner_ty).intern(Interner)
371            }
372            TypeRef::Reference(ref_) => {
373                let inner_ty = self.lower_ty(ref_.ty);
374                // FIXME: It should infer the eldided lifetimes instead of stubbing with static
375                let lifetime = ref_
376                    .lifetime
377                    .as_ref()
378                    .map_or_else(error_lifetime, |&lr| self.lower_lifetime(lr));
379                TyKind::Ref(lower_to_chalk_mutability(ref_.mutability), lifetime, inner_ty)
380                    .intern(Interner)
381            }
382            TypeRef::Placeholder => TyKind::Error.intern(Interner),
383            TypeRef::Fn(fn_) => {
384                let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
385                    let (params, ret) = fn_.split_params_and_ret();
386                    let mut subst = Vec::with_capacity(fn_.params.len());
387                    ctx.with_lifetime_elision(
388                        LifetimeElisionKind::AnonymousCreateParameter { report_in_path: false },
389                        |ctx| {
390                            subst.extend(params.iter().map(|&(_, tr)| ctx.lower_ty(tr)));
391                        },
392                    );
393                    ctx.with_lifetime_elision(LifetimeElisionKind::for_fn_ret(), |ctx| {
394                        subst.push(ctx.lower_ty(ret));
395                    });
396                    Substitution::from_iter(Interner, subst)
397                });
398                TyKind::Function(FnPointer {
399                    num_binders: 0, // FIXME lower `for<'a> fn()` correctly
400                    sig: FnSig {
401                        abi: fn_.abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol),
402                        safety: if fn_.is_unsafe { Safety::Unsafe } else { Safety::Safe },
403                        variadic: fn_.is_varargs,
404                    },
405                    substitution: FnSubst(substs),
406                })
407                .intern(Interner)
408            }
409            TypeRef::DynTrait(bounds) => self.lower_dyn_trait(bounds),
410            TypeRef::ImplTrait(bounds) => {
411                match self.impl_trait_mode.mode {
412                    ImplTraitLoweringMode::Opaque => {
413                        let origin = match self.def {
414                            GenericDefId::FunctionId(it) => Either::Left(it),
415                            GenericDefId::TypeAliasId(it) => Either::Right(it),
416                            _ => panic!(
417                                "opaque impl trait lowering must be in function or type alias"
418                            ),
419                        };
420
421                        // this dance is to make sure the data is in the right
422                        // place even if we encounter more opaque types while
423                        // lowering the bounds
424                        let idx = self.impl_trait_mode.opaque_type_data.alloc(ImplTrait {
425                            bounds: crate::make_single_type_binders(Vec::default()),
426                        });
427                        // We don't want to lower the bounds inside the binders
428                        // we're currently in, because they don't end up inside
429                        // those binders. E.g. when we have `impl Trait<impl
430                        // OtherTrait<T>>`, the `impl OtherTrait<T>` can't refer
431                        // to the self parameter from `impl Trait`, and the
432                        // bounds aren't actually stored nested within each
433                        // other, but separately. So if the `T` refers to a type
434                        // parameter of the outer function, it's just one binder
435                        // away instead of two.
436                        let actual_opaque_type_data = self
437                            .with_debruijn(DebruijnIndex::INNERMOST, |ctx| {
438                                ctx.lower_impl_trait(bounds, self.resolver.krate())
439                            });
440                        self.impl_trait_mode.opaque_type_data[idx] = actual_opaque_type_data;
441
442                        let impl_trait_id = origin.either(
443                            |f| ImplTraitId::ReturnTypeImplTrait(f, idx),
444                            |a| ImplTraitId::TypeAliasImplTrait(a, idx),
445                        );
446                        let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
447                        let generics = generics(self.db, origin.either(|f| f.into(), |a| a.into()));
448                        let parameters = generics.bound_vars_subst(self.db, self.in_binders);
449                        TyKind::OpaqueType(opaque_ty_id, parameters).intern(Interner)
450                    }
451                    ImplTraitLoweringMode::Disallowed => {
452                        // FIXME: report error
453                        TyKind::Error.intern(Interner)
454                    }
455                }
456            }
457            TypeRef::Error => TyKind::Error.intern(Interner),
458        };
459        (ty, res)
460    }
461
462    /// This is only for `generic_predicates_for_param`, where we can't just
463    /// lower the self types of the predicates since that could lead to cycles.
464    /// So we just check here if the `type_ref` resolves to a generic param, and which.
465    fn lower_ty_only_param(&mut self, type_ref_id: TypeRefId) -> Option<TypeOrConstParamId> {
466        let type_ref = &self.store[type_ref_id];
467        let path = match type_ref {
468            TypeRef::Path(path) => path,
469            &TypeRef::TypeParam(idx) => return Some(idx.into()),
470            _ => return None,
471        };
472        if path.type_anchor().is_some() {
473            return None;
474        }
475        if path.segments().len() > 1 {
476            return None;
477        }
478        let mut ctx = self.at_path(PathId::from_type_ref_unchecked(type_ref_id));
479        let resolution = match ctx.resolve_path_in_type_ns() {
480            Some((it, None)) => it,
481            _ => return None,
482        };
483        match resolution {
484            TypeNs::GenericParam(param_id) => Some(param_id.into()),
485            _ => None,
486        }
487    }
488
489    #[inline]
490    fn on_path_diagnostic_callback(type_ref: TypeRefId) -> PathDiagnosticCallback<'static> {
491        PathDiagnosticCallback {
492            data: Either::Left(PathDiagnosticCallbackData(type_ref)),
493            callback: |data, this, diag| {
494                let type_ref = data.as_ref().left().unwrap().0;
495                this.push_diagnostic(type_ref, TyLoweringDiagnosticKind::PathDiagnostic(diag))
496            },
497        }
498    }
499
500    #[inline]
501    fn at_path(&mut self, path_id: PathId) -> PathLoweringContext<'_, 'a> {
502        PathLoweringContext::new(
503            self,
504            Self::on_path_diagnostic_callback(path_id.type_ref()),
505            &self.store[path_id],
506        )
507    }
508
509    pub(crate) fn lower_path(&mut self, path: &Path, path_id: PathId) -> (Ty, Option<TypeNs>) {
510        // Resolve the path (in type namespace)
511        if let Some(type_ref) = path.type_anchor() {
512            let (ty, res) = self.lower_ty_ext(type_ref);
513            let mut ctx = self.at_path(path_id);
514            return ctx.lower_ty_relative_path(ty, res, false);
515        }
516
517        let mut ctx = self.at_path(path_id);
518        let (resolution, remaining_index) = match ctx.resolve_path_in_type_ns() {
519            Some(it) => it,
520            None => return (TyKind::Error.intern(Interner), None),
521        };
522
523        if matches!(resolution, TypeNs::TraitId(_)) && remaining_index.is_none() {
524            // trait object type without dyn
525            let bound = TypeBound::Path(path_id, TraitBoundModifier::None);
526            let ty = self.lower_dyn_trait(&[bound]);
527            return (ty, None);
528        }
529
530        ctx.lower_partly_resolved_path(resolution, false)
531    }
532
533    fn lower_trait_ref_from_path(
534        &mut self,
535        path_id: PathId,
536        explicit_self_ty: Ty,
537    ) -> Option<(TraitRef, PathLoweringContext<'_, 'a>)> {
538        let mut ctx = self.at_path(path_id);
539        let resolved = match ctx.resolve_path_in_type_ns_fully()? {
540            // FIXME(trait_alias): We need to handle trait alias here.
541            TypeNs::TraitId(tr) => tr,
542            _ => return None,
543        };
544        Some((ctx.lower_trait_ref_from_resolved_path(resolved, explicit_self_ty, false), ctx))
545    }
546
547    fn lower_trait_ref(
548        &mut self,
549        trait_ref: &HirTraitRef,
550        explicit_self_ty: Ty,
551    ) -> Option<TraitRef> {
552        self.lower_trait_ref_from_path(trait_ref.path, explicit_self_ty).map(|it| it.0)
553    }
554
555    /// When lowering predicates from parents (impl, traits) for children defs (fns, consts, types), `generics` should
556    /// contain the `Generics` for the **child**, while `predicate_owner` should contain the `GenericDefId` of the
557    /// **parent**. This is important so we generate the correct bound var/placeholder.
558    pub(crate) fn lower_where_predicate<'b>(
559        &'b mut self,
560        where_predicate: &'b WherePredicate,
561        ignore_bindings: bool,
562    ) -> impl Iterator<Item = QuantifiedWhereClause> + use<'a, 'b> {
563        match where_predicate {
564            WherePredicate::ForLifetime { target, bound, .. }
565            | WherePredicate::TypeBound { target, bound } => {
566                let self_ty = self.lower_ty(*target);
567                Either::Left(self.lower_type_bound(bound, self_ty, ignore_bindings))
568            }
569            &WherePredicate::Lifetime { bound, target } => Either::Right(iter::once(
570                crate::wrap_empty_binders(WhereClause::LifetimeOutlives(LifetimeOutlives {
571                    a: self.lower_lifetime(bound),
572                    b: self.lower_lifetime(target),
573                })),
574            )),
575        }
576        .into_iter()
577    }
578
579    pub(crate) fn lower_type_bound<'b>(
580        &'b mut self,
581        bound: &'b TypeBound,
582        self_ty: Ty,
583        ignore_bindings: bool,
584    ) -> impl Iterator<Item = QuantifiedWhereClause> + use<'b, 'a> {
585        let mut assoc_bounds = None;
586        let mut clause = None;
587        match bound {
588            &TypeBound::Path(path, TraitBoundModifier::None) | &TypeBound::ForLifetime(_, path) => {
589                // FIXME Don't silently drop the hrtb lifetimes here
590                if let Some((trait_ref, mut ctx)) =
591                    self.lower_trait_ref_from_path(path, self_ty.clone())
592                {
593                    // FIXME(sized-hierarchy): Remove this bound modifications once we have implemented
594                    // sized-hierarchy correctly.
595                    let meta_sized = LangItem::MetaSized
596                        .resolve_trait(ctx.ty_ctx().db, ctx.ty_ctx().resolver.krate());
597                    let pointee_sized = LangItem::PointeeSized
598                        .resolve_trait(ctx.ty_ctx().db, ctx.ty_ctx().resolver.krate());
599                    let destruct = LangItem::Destruct
600                        .resolve_trait(ctx.ty_ctx().db, ctx.ty_ctx().resolver.krate());
601                    let hir_trait_id = trait_ref.hir_trait_id();
602                    if meta_sized.is_some_and(|it| it == hir_trait_id)
603                        || destruct.is_some_and(|it| it == hir_trait_id)
604                    {
605                        // Ignore this bound
606                    } else if pointee_sized.is_some_and(|it| it == hir_trait_id) {
607                        // Regard this as `?Sized` bound
608                        ctx.ty_ctx().unsized_types.insert(self_ty);
609                    } else {
610                        if !ignore_bindings {
611                            assoc_bounds =
612                                ctx.assoc_type_bindings_from_type_bound(trait_ref.clone());
613                        }
614                        clause =
615                            Some(crate::wrap_empty_binders(WhereClause::Implemented(trait_ref)));
616                    }
617                }
618            }
619            &TypeBound::Path(path, TraitBoundModifier::Maybe) => {
620                let sized_trait = LangItem::Sized.resolve_trait(self.db, self.resolver.krate());
621                // Don't lower associated type bindings as the only possible relaxed trait bound
622                // `?Sized` has no of them.
623                // If we got another trait here ignore the bound completely.
624                let trait_id = self
625                    .lower_trait_ref_from_path(path, self_ty.clone())
626                    .map(|(trait_ref, _)| trait_ref.hir_trait_id());
627                if trait_id == sized_trait {
628                    self.unsized_types.insert(self_ty);
629                }
630            }
631            &TypeBound::Lifetime(l) => {
632                let lifetime = self.lower_lifetime(l);
633                clause = Some(crate::wrap_empty_binders(WhereClause::TypeOutlives(TypeOutlives {
634                    ty: self_ty,
635                    lifetime,
636                })));
637            }
638            TypeBound::Use(_) | TypeBound::Error => {}
639        }
640        clause.into_iter().chain(assoc_bounds.into_iter().flatten())
641    }
642
643    fn lower_dyn_trait(&mut self, bounds: &[TypeBound]) -> Ty {
644        let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
645        // INVARIANT: The principal trait bound, if present, must come first. Others may be in any
646        // order but should be in the same order for the same set but possibly different order of
647        // bounds in the input.
648        // INVARIANT: If this function returns `DynTy`, there should be at least one trait bound.
649        // These invariants are utilized by `TyExt::dyn_trait()` and chalk.
650        let mut lifetime = None;
651        let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
652            let mut lowered_bounds = Vec::new();
653            for b in bounds {
654                ctx.lower_type_bound(b, self_ty.clone(), false).for_each(|b| {
655                    let filter = match b.skip_binders() {
656                        WhereClause::Implemented(_) | WhereClause::AliasEq(_) => true,
657                        WhereClause::LifetimeOutlives(_) => false,
658                        WhereClause::TypeOutlives(t) => {
659                            lifetime = Some(t.lifetime.clone());
660                            false
661                        }
662                    };
663                    if filter {
664                        lowered_bounds.push(b);
665                    }
666                });
667            }
668
669            let mut multiple_regular_traits = false;
670            let mut multiple_same_projection = false;
671            lowered_bounds.sort_unstable_by(|lhs, rhs| {
672                use std::cmp::Ordering;
673                match (lhs.skip_binders(), rhs.skip_binders()) {
674                    (WhereClause::Implemented(lhs), WhereClause::Implemented(rhs)) => {
675                        let lhs_id = lhs.trait_id;
676                        let lhs_is_auto = ctx
677                            .db
678                            .trait_signature(from_chalk_trait_id(lhs_id))
679                            .flags
680                            .contains(TraitFlags::AUTO);
681                        let rhs_id = rhs.trait_id;
682                        let rhs_is_auto = ctx
683                            .db
684                            .trait_signature(from_chalk_trait_id(rhs_id))
685                            .flags
686                            .contains(TraitFlags::AUTO);
687
688                        if !lhs_is_auto && !rhs_is_auto {
689                            multiple_regular_traits = true;
690                        }
691                        // Note that the ordering here is important; this ensures the invariant
692                        // mentioned above.
693                        (lhs_is_auto, lhs_id).cmp(&(rhs_is_auto, rhs_id))
694                    }
695                    (WhereClause::Implemented(_), _) => Ordering::Less,
696                    (_, WhereClause::Implemented(_)) => Ordering::Greater,
697                    (WhereClause::AliasEq(lhs), WhereClause::AliasEq(rhs)) => {
698                        match (&lhs.alias, &rhs.alias) {
699                            (AliasTy::Projection(lhs_proj), AliasTy::Projection(rhs_proj)) => {
700                                // We only compare the `associated_ty_id`s. We shouldn't have
701                                // multiple bounds for an associated type in the correct Rust code,
702                                // and if we do, we error out.
703                                if lhs_proj.associated_ty_id == rhs_proj.associated_ty_id {
704                                    multiple_same_projection = true;
705                                }
706                                lhs_proj.associated_ty_id.cmp(&rhs_proj.associated_ty_id)
707                            }
708                            // We don't produce `AliasTy::Opaque`s yet.
709                            _ => unreachable!(),
710                        }
711                    }
712                    // `WhereClause::{TypeOutlives, LifetimeOutlives}` have been filtered out
713                    _ => unreachable!(),
714                }
715            });
716
717            if multiple_regular_traits || multiple_same_projection {
718                return None;
719            }
720
721            lowered_bounds.first().and_then(|b| b.trait_id())?;
722
723            // As multiple occurrences of the same auto traits *are* permitted, we deduplicate the
724            // bounds. We shouldn't have repeated elements besides auto traits at this point.
725            lowered_bounds.dedup();
726
727            Some(QuantifiedWhereClauses::from_iter(Interner, lowered_bounds))
728        });
729
730        if let Some(bounds) = bounds {
731            let bounds = crate::make_single_type_binders(bounds);
732            TyKind::Dyn(DynTy {
733                bounds,
734                lifetime: match lifetime {
735                    Some(it) => match it.bound_var(Interner) {
736                        Some(bound_var) => bound_var
737                            .shifted_out_to(DebruijnIndex::new(2))
738                            .map(|bound_var| LifetimeData::BoundVar(bound_var).intern(Interner))
739                            .unwrap_or(it),
740                        None => it,
741                    },
742                    None => error_lifetime(),
743                },
744            })
745            .intern(Interner)
746        } else {
747            // FIXME: report error
748            // (additional non-auto traits, associated type rebound, or no resolved trait)
749            TyKind::Error.intern(Interner)
750        }
751    }
752
753    fn lower_impl_trait(&mut self, bounds: &[TypeBound], krate: Crate) -> ImplTrait {
754        cov_mark::hit!(lower_rpit);
755        let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
756        let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
757            let mut predicates = Vec::new();
758            for b in bounds {
759                predicates.extend(ctx.lower_type_bound(b, self_ty.clone(), false));
760            }
761
762            if !ctx.unsized_types.contains(&self_ty) {
763                let sized_trait =
764                    LangItem::Sized.resolve_trait(ctx.db, krate).map(to_chalk_trait_id);
765                let sized_clause = sized_trait.map(|trait_id| {
766                    let clause = WhereClause::Implemented(TraitRef {
767                        trait_id,
768                        substitution: Substitution::from1(Interner, self_ty.clone()),
769                    });
770                    crate::wrap_empty_binders(clause)
771                });
772                predicates.extend(sized_clause);
773            }
774            predicates.shrink_to_fit();
775            predicates
776        });
777        ImplTrait { bounds: crate::make_single_type_binders(predicates) }
778    }
779
780    pub fn lower_lifetime(&self, lifetime: LifetimeRefId) -> Lifetime {
781        match self.resolver.resolve_lifetime(&self.store[lifetime]) {
782            Some(resolution) => match resolution {
783                LifetimeNs::Static => static_lifetime(),
784                LifetimeNs::LifetimeParam(id) => match self.type_param_mode {
785                    ParamLoweringMode::Placeholder => {
786                        let generics = self.generics();
787                        let idx = generics.lifetime_idx(id).unwrap();
788                        LifetimeData::Placeholder(lt_to_placeholder_idx(self.db, id, idx as u32))
789                    }
790                    ParamLoweringMode::Variable => {
791                        let idx = match self.generics().lifetime_idx(id) {
792                            None => return error_lifetime(),
793                            Some(idx) => idx,
794                        };
795
796                        LifetimeData::BoundVar(BoundVar::new(self.in_binders, idx))
797                    }
798                }
799                .intern(Interner),
800            },
801            None => error_lifetime(),
802        }
803    }
804}
805
806/// Build the signature of a callable item (function, struct or enum variant).
807pub(crate) fn callable_item_signature_query(db: &dyn HirDatabase, def: CallableDefId) -> PolyFnSig {
808    match def {
809        CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f),
810        CallableDefId::StructId(s) => fn_sig_for_struct_constructor(db, s),
811        CallableDefId::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e),
812    }
813}
814
815fn named_associated_type_shorthand_candidates<R>(
816    db: &dyn HirDatabase,
817    // If the type parameter is defined in an impl and we're in a method, there
818    // might be additional where clauses to consider
819    def: GenericDefId,
820    res: TypeNs,
821    assoc_name: Option<Name>,
822    // Do NOT let `cb` touch `TraitRef` outside of `TyLoweringContext`. Its substitution contains
823    // free `BoundVar`s that need to be shifted and only `TyLoweringContext` knows how to do that
824    // properly (see `TyLoweringContext::select_associated_type()`).
825    mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
826) -> Option<R> {
827    let mut search = |t| {
828        all_super_trait_refs(db, t, |t| {
829            let data = t.hir_trait_id().trait_items(db);
830
831            for (name, assoc_id) in &data.items {
832                if let AssocItemId::TypeAliasId(alias) = assoc_id
833                    && let Some(result) = cb(name, &t, *alias)
834                {
835                    return Some(result);
836                }
837            }
838            None
839        })
840    };
841
842    match res {
843        TypeNs::SelfType(impl_id) => {
844            // we're _in_ the impl -- the binders get added back later. Correct,
845            // but it would be nice to make this more explicit
846            let trait_ref = db.impl_trait(impl_id)?.into_value_and_skipped_binders().0;
847
848            let impl_id_as_generic_def: GenericDefId = impl_id.into();
849            if impl_id_as_generic_def != def {
850                let subst = TyBuilder::subst_for_def(db, impl_id, None)
851                    .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
852                    .build();
853                let trait_ref = subst.apply(trait_ref, Interner);
854                search(trait_ref)
855            } else {
856                search(trait_ref)
857            }
858        }
859        TypeNs::GenericParam(param_id) => {
860            let predicates = db.generic_predicates_for_param(def, param_id.into(), assoc_name);
861            let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
862                // FIXME: how to correctly handle higher-ranked bounds here?
863                WhereClause::Implemented(tr) => search(
864                    tr.clone()
865                        .shifted_out_to(Interner, DebruijnIndex::ONE)
866                        .expect("FIXME unexpected higher-ranked trait bound"),
867                ),
868                _ => None,
869            });
870            if res.is_some() {
871                return res;
872            }
873            // Handle `Self::Type` referring to own associated type in trait definitions
874            if let GenericDefId::TraitId(trait_id) = param_id.parent() {
875                let trait_generics = generics(db, trait_id.into());
876                if trait_generics[param_id.local_id()].is_trait_self() {
877                    let trait_ref = TyBuilder::trait_ref(db, trait_id)
878                        .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
879                        .build();
880                    return search(trait_ref);
881                }
882            }
883            None
884        }
885        _ => None,
886    }
887}
888
889pub(crate) type Diagnostics = Option<ThinArc<(), TyLoweringDiagnostic>>;
890
891pub(crate) fn create_diagnostics(diagnostics: Vec<TyLoweringDiagnostic>) -> Diagnostics {
892    (!diagnostics.is_empty()).then(|| ThinArc::from_header_and_iter((), diagnostics.into_iter()))
893}
894
895pub(crate) fn field_types_query(
896    db: &dyn HirDatabase,
897    variant_id: VariantId,
898) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> {
899    db.field_types_with_diagnostics(variant_id).0
900}
901
902/// Build the type of all specific fields of a struct or enum variant.
903pub(crate) fn field_types_with_diagnostics_query(
904    db: &dyn HirDatabase,
905    variant_id: VariantId,
906) -> (Arc<ArenaMap<LocalFieldId, Binders<Ty>>>, Diagnostics) {
907    let var_data = variant_id.fields(db);
908    let fields = var_data.fields();
909    if fields.is_empty() {
910        return (Arc::new(ArenaMap::default()), None);
911    }
912
913    let (resolver, def): (_, GenericDefId) = match variant_id {
914        VariantId::StructId(it) => (it.resolver(db), it.into()),
915        VariantId::UnionId(it) => (it.resolver(db), it.into()),
916        VariantId::EnumVariantId(it) => (it.resolver(db), it.lookup(db).parent.into()),
917    };
918    let generics = generics(db, def);
919    let mut res = ArenaMap::default();
920    let mut ctx = TyLoweringContext::new(
921        db,
922        &resolver,
923        &var_data.store,
924        def,
925        LifetimeElisionKind::AnonymousReportError,
926    )
927    .with_type_param_mode(ParamLoweringMode::Variable);
928    for (field_id, field_data) in fields.iter() {
929        res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(field_data.type_ref)));
930    }
931    (Arc::new(res), create_diagnostics(ctx.diagnostics))
932}
933
934/// This query exists only to be used when resolving short-hand associated types
935/// like `T::Item`.
936///
937/// See the analogous query in rustc and its comment:
938/// <https://github.com/rust-lang/rust/blob/9150f844e2624eb013ec78ca08c1d416e6644026/src/librustc_typeck/astconv.rs#L46>
939/// This is a query mostly to handle cycles somewhat gracefully; e.g. the
940/// following bounds are disallowed: `T: Foo<U::Item>, U: Foo<T::Item>`, but
941/// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
942pub(crate) fn generic_predicates_for_param_query(
943    db: &dyn HirDatabase,
944    def: GenericDefId,
945    param_id: TypeOrConstParamId,
946    assoc_name: Option<Name>,
947) -> GenericPredicates {
948    let generics = generics(db, def);
949    if generics.has_no_predicates() && generics.is_empty() {
950        return GenericPredicates(None);
951    }
952
953    let resolver = def.resolver(db);
954    let mut ctx = TyLoweringContext::new(
955        db,
956        &resolver,
957        generics.store(),
958        def,
959        LifetimeElisionKind::AnonymousReportError,
960    )
961    .with_type_param_mode(ParamLoweringMode::Variable);
962
963    // we have to filter out all other predicates *first*, before attempting to lower them
964    let predicate = |pred: &_, ctx: &mut TyLoweringContext<'_>| match pred {
965        WherePredicate::ForLifetime { target, bound, .. }
966        | WherePredicate::TypeBound { target, bound, .. } => {
967            let invalid_target = { ctx.lower_ty_only_param(*target) != Some(param_id) };
968            if invalid_target {
969                // FIXME(sized-hierarchy): Revisit and adjust this properly once we have implemented
970                // sized-hierarchy correctly.
971                // If this is filtered out without lowering, `?Sized` or `PointeeSized` is not gathered into
972                // `ctx.unsized_types`
973                let lower = || -> bool {
974                    match bound {
975                        TypeBound::Path(_, TraitBoundModifier::Maybe) => true,
976                        TypeBound::Path(path, _) | TypeBound::ForLifetime(_, path) => {
977                            let TypeRef::Path(path) = &ctx.store[path.type_ref()] else {
978                                return false;
979                            };
980                            let Some(pointee_sized) =
981                                LangItem::PointeeSized.resolve_trait(ctx.db, ctx.resolver.krate())
982                            else {
983                                return false;
984                            };
985                            // Lower the path directly with `Resolver` instead of PathLoweringContext`
986                            // to prevent diagnostics duplications.
987                            ctx.resolver.resolve_path_in_type_ns_fully(ctx.db, path).is_some_and(
988                                |it| matches!(it, TypeNs::TraitId(tr) if tr == pointee_sized),
989                            )
990                        }
991                        _ => false,
992                    }
993                }();
994                if lower {
995                    ctx.lower_where_predicate(pred, true).for_each(drop);
996                }
997                return false;
998            }
999
1000            match bound {
1001                &TypeBound::ForLifetime(_, path) | &TypeBound::Path(path, _) => {
1002                    // Only lower the bound if the trait could possibly define the associated
1003                    // type we're looking for.
1004                    let path = &ctx.store[path];
1005
1006                    let Some(assoc_name) = &assoc_name else { return true };
1007                    let Some(TypeNs::TraitId(tr)) =
1008                        resolver.resolve_path_in_type_ns_fully(db, path)
1009                    else {
1010                        return false;
1011                    };
1012
1013                    all_super_traits(db, tr).iter().any(|tr| {
1014                        tr.trait_items(db).items.iter().any(|(name, item)| {
1015                            matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name
1016                        })
1017                    })
1018                }
1019                TypeBound::Use(_) | TypeBound::Lifetime(_) | TypeBound::Error => false,
1020            }
1021        }
1022        WherePredicate::Lifetime { .. } => false,
1023    };
1024    let mut predicates = Vec::new();
1025    for maybe_parent_generics in
1026        std::iter::successors(Some(&generics), |generics| generics.parent_generics())
1027    {
1028        ctx.store = maybe_parent_generics.store();
1029        for pred in maybe_parent_generics.where_predicates() {
1030            if predicate(pred, &mut ctx) {
1031                predicates.extend(
1032                    ctx.lower_where_predicate(pred, true).map(|p| make_binders(db, &generics, p)),
1033                );
1034            }
1035        }
1036    }
1037
1038    let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1039    if !subst.is_empty(Interner) {
1040        let explicitly_unsized_tys = ctx.unsized_types;
1041        if let Some(implicitly_sized_predicates) = implicitly_sized_clauses(
1042            db,
1043            param_id.parent,
1044            &explicitly_unsized_tys,
1045            &subst,
1046            &resolver,
1047        ) {
1048            predicates.extend(
1049                implicitly_sized_predicates
1050                    .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p))),
1051            );
1052        };
1053    }
1054    GenericPredicates(predicates.is_empty().not().then(|| predicates.into()))
1055}
1056
1057pub(crate) fn generic_predicates_for_param_cycle_result(
1058    _db: &dyn HirDatabase,
1059    _def: GenericDefId,
1060    _param_id: TypeOrConstParamId,
1061    _assoc_name: Option<Name>,
1062) -> GenericPredicates {
1063    GenericPredicates(None)
1064}
1065
1066pub(crate) fn trait_environment_for_body_query(
1067    db: &dyn HirDatabase,
1068    def: DefWithBodyId,
1069) -> Arc<TraitEnvironment> {
1070    let Some(def) = def.as_generic_def_id(db) else {
1071        let krate = def.module(db).krate();
1072        return TraitEnvironment::empty(krate);
1073    };
1074    db.trait_environment(def)
1075}
1076
1077pub(crate) fn trait_environment_query(
1078    db: &dyn HirDatabase,
1079    def: GenericDefId,
1080) -> Arc<TraitEnvironment> {
1081    let generics = generics(db, def);
1082    if generics.has_no_predicates() && generics.is_empty() {
1083        return TraitEnvironment::empty(def.krate(db));
1084    }
1085
1086    let resolver = def.resolver(db);
1087    let mut ctx = TyLoweringContext::new(
1088        db,
1089        &resolver,
1090        generics.store(),
1091        def,
1092        LifetimeElisionKind::AnonymousReportError,
1093    )
1094    .with_type_param_mode(ParamLoweringMode::Placeholder);
1095    let mut traits_in_scope = Vec::new();
1096    let mut clauses = Vec::new();
1097    for maybe_parent_generics in
1098        std::iter::successors(Some(&generics), |generics| generics.parent_generics())
1099    {
1100        ctx.store = maybe_parent_generics.store();
1101        for pred in maybe_parent_generics.where_predicates() {
1102            for pred in ctx.lower_where_predicate(pred, false) {
1103                if let WhereClause::Implemented(tr) = pred.skip_binders() {
1104                    traits_in_scope
1105                        .push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id()));
1106                }
1107                let program_clause: Binders<DomainGoal> =
1108                    pred.map(|pred| pred.into_from_env_goal(Interner).cast(Interner));
1109                clauses.push(program_clause);
1110            }
1111        }
1112    }
1113
1114    if let Some(trait_id) = def.assoc_trait_container(db) {
1115        // add `Self: Trait<T1, T2, ...>` to the environment in trait
1116        // function default implementations (and speculative code
1117        // inside consts or type aliases)
1118        cov_mark::hit!(trait_self_implements_self);
1119        let substs = TyBuilder::placeholder_subst(db, trait_id);
1120        let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
1121        let pred = WhereClause::Implemented(trait_ref);
1122        clauses.push(Binders::empty(
1123            Interner,
1124            pred.cast::<DomainGoal>(Interner).into_from_env_goal(Interner),
1125        ));
1126    }
1127
1128    let subst = generics.placeholder_subst(db);
1129    if !subst.is_empty(Interner) {
1130        let explicitly_unsized_tys = ctx.unsized_types;
1131        if let Some(implicitly_sized_clauses) =
1132            implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver)
1133        {
1134            clauses.extend(implicitly_sized_clauses.map(|pred| {
1135                Binders::empty(
1136                    Interner,
1137                    pred.into_from_env_goal(Interner).cast::<DomainGoal>(Interner),
1138                )
1139            }));
1140        };
1141    }
1142
1143    let clauses = chalk_ir::ProgramClauses::from_iter(
1144        Interner,
1145        clauses.into_iter().map(|g| {
1146            chalk_ir::ProgramClause::new(
1147                Interner,
1148                chalk_ir::ProgramClauseData(g.map(|g| chalk_ir::ProgramClauseImplication {
1149                    consequence: g,
1150                    conditions: chalk_ir::Goals::empty(Interner),
1151                    constraints: chalk_ir::Constraints::empty(Interner),
1152                    priority: chalk_ir::ClausePriority::High,
1153                })),
1154            )
1155        }),
1156    );
1157    let env = chalk_ir::Environment { clauses };
1158
1159    TraitEnvironment::new(resolver.krate(), None, traits_in_scope.into_boxed_slice(), env)
1160}
1161
1162#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1163pub struct GenericPredicates(Option<Arc<[Binders<QuantifiedWhereClause>]>>);
1164
1165impl ops::Deref for GenericPredicates {
1166    type Target = [Binders<crate::QuantifiedWhereClause>];
1167
1168    fn deref(&self) -> &Self::Target {
1169        self.0.as_deref().unwrap_or(&[])
1170    }
1171}
1172
1173/// Resolve the where clause(s) of an item with generics.
1174pub(crate) fn generic_predicates_query(
1175    db: &dyn HirDatabase,
1176    def: GenericDefId,
1177) -> GenericPredicates {
1178    generic_predicates_filtered_by(db, def, |_, _| true).0
1179}
1180
1181/// Resolve the where clause(s) of an item with generics,
1182/// with a given filter
1183fn generic_predicates_filtered_by<F>(
1184    db: &dyn HirDatabase,
1185    def: GenericDefId,
1186    filter: F,
1187) -> (GenericPredicates, Diagnostics)
1188where
1189    F: Fn(&WherePredicate, GenericDefId) -> bool,
1190{
1191    let generics = generics(db, def);
1192    if generics.has_no_predicates() && generics.is_empty() {
1193        return (GenericPredicates(None), None);
1194    }
1195
1196    let resolver = def.resolver(db);
1197    let mut ctx = TyLoweringContext::new(
1198        db,
1199        &resolver,
1200        generics.store(),
1201        def,
1202        LifetimeElisionKind::AnonymousReportError,
1203    )
1204    .with_type_param_mode(ParamLoweringMode::Variable);
1205
1206    let mut predicates = Vec::new();
1207    for maybe_parent_generics in
1208        std::iter::successors(Some(&generics), |generics| generics.parent_generics())
1209    {
1210        ctx.store = maybe_parent_generics.store();
1211        for pred in maybe_parent_generics.where_predicates() {
1212            if filter(pred, maybe_parent_generics.def()) {
1213                // We deliberately use `generics` and not `maybe_parent_generics` here. This is not a mistake!
1214                // If we use the parent generics
1215                predicates.extend(
1216                    ctx.lower_where_predicate(pred, false).map(|p| make_binders(db, &generics, p)),
1217                );
1218            }
1219        }
1220    }
1221
1222    if !generics.is_empty() {
1223        let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1224        let explicitly_unsized_tys = ctx.unsized_types;
1225        if let Some(implicitly_sized_predicates) =
1226            implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver)
1227        {
1228            predicates.extend(
1229                implicitly_sized_predicates
1230                    .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p))),
1231            );
1232        };
1233    }
1234
1235    (
1236        GenericPredicates(predicates.is_empty().not().then(|| predicates.into())),
1237        create_diagnostics(ctx.diagnostics),
1238    )
1239}
1240
1241/// Generate implicit `: Sized` predicates for all generics that has no `?Sized` bound.
1242/// Exception is Self of a trait def.
1243fn implicitly_sized_clauses<'db, 'a, 'subst: 'a>(
1244    db: &'db dyn HirDatabase,
1245    def: GenericDefId,
1246    explicitly_unsized_tys: &'a FxHashSet<Ty>,
1247    substitution: &'subst Substitution,
1248    resolver: &Resolver<'db>,
1249) -> Option<impl Iterator<Item = WhereClause>> {
1250    let sized_trait = LangItem::Sized.resolve_trait(db, resolver.krate()).map(to_chalk_trait_id)?;
1251
1252    let trait_self_idx = trait_self_param_idx(db, def);
1253
1254    Some(
1255        substitution
1256            .iter(Interner)
1257            .enumerate()
1258            .filter_map(
1259                move |(idx, generic_arg)| {
1260                    if Some(idx) == trait_self_idx { None } else { Some(generic_arg) }
1261                },
1262            )
1263            .filter_map(|generic_arg| generic_arg.ty(Interner))
1264            .filter(move |&self_ty| !explicitly_unsized_tys.contains(self_ty))
1265            .map(move |self_ty| {
1266                WhereClause::Implemented(TraitRef {
1267                    trait_id: sized_trait,
1268                    substitution: Substitution::from1(Interner, self_ty.clone()),
1269                })
1270            }),
1271    )
1272}
1273
1274#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1275pub struct GenericDefaults(Option<Arc<[Binders<crate::GenericArg>]>>);
1276
1277impl ops::Deref for GenericDefaults {
1278    type Target = [Binders<crate::GenericArg>];
1279
1280    fn deref(&self) -> &Self::Target {
1281        self.0.as_deref().unwrap_or(&[])
1282    }
1283}
1284
1285pub(crate) fn generic_defaults_query(db: &dyn HirDatabase, def: GenericDefId) -> GenericDefaults {
1286    db.generic_defaults_with_diagnostics(def).0
1287}
1288
1289/// Resolve the default type params from generics.
1290///
1291/// Diagnostics are only returned for this `GenericDefId` (returned defaults include parents).
1292pub(crate) fn generic_defaults_with_diagnostics_query(
1293    db: &dyn HirDatabase,
1294    def: GenericDefId,
1295) -> (GenericDefaults, Diagnostics) {
1296    let generic_params = generics(db, def);
1297    if generic_params.is_empty() {
1298        return (GenericDefaults(None), None);
1299    }
1300    let resolver = def.resolver(db);
1301
1302    let mut ctx = TyLoweringContext::new(
1303        db,
1304        &resolver,
1305        generic_params.store(),
1306        def,
1307        LifetimeElisionKind::AnonymousReportError,
1308    )
1309    .with_impl_trait_mode(ImplTraitLoweringMode::Disallowed)
1310    .with_type_param_mode(ParamLoweringMode::Variable);
1311    let mut idx = 0;
1312    let mut has_any_default = false;
1313    let mut defaults = generic_params
1314        .iter_parents_with_store()
1315        .map(|((id, p), store)| {
1316            ctx.store = store;
1317            let (result, has_default) = handle_generic_param(&mut ctx, idx, id, p, &generic_params);
1318            has_any_default |= has_default;
1319            idx += 1;
1320            result
1321        })
1322        .collect::<Vec<_>>();
1323    ctx.diagnostics.clear(); // Don't include diagnostics from the parent.
1324    defaults.extend(generic_params.iter_self().map(|(id, p)| {
1325        let (result, has_default) = handle_generic_param(&mut ctx, idx, id, p, &generic_params);
1326        has_any_default |= has_default;
1327        idx += 1;
1328        result
1329    }));
1330    let diagnostics = create_diagnostics(mem::take(&mut ctx.diagnostics));
1331    let defaults = if has_any_default {
1332        GenericDefaults(Some(Arc::from_iter(defaults)))
1333    } else {
1334        GenericDefaults(None)
1335    };
1336    return (defaults, diagnostics);
1337
1338    fn handle_generic_param(
1339        ctx: &mut TyLoweringContext<'_>,
1340        idx: usize,
1341        id: GenericParamId,
1342        p: GenericParamDataRef<'_>,
1343        generic_params: &Generics,
1344    ) -> (Binders<crate::GenericArg>, bool) {
1345        let binders = variable_kinds_from_iter(ctx.db, generic_params.iter_id().take(idx));
1346        match p {
1347            GenericParamDataRef::TypeParamData(p) => {
1348                let ty = p.default.as_ref().map_or_else(
1349                    || TyKind::Error.intern(Interner),
1350                    |ty| {
1351                        // Each default can only refer to previous parameters.
1352                        // Type variable default referring to parameter coming
1353                        // after it is forbidden (FIXME: report diagnostic)
1354                        fallback_bound_vars(ctx.lower_ty(*ty), idx)
1355                    },
1356                );
1357                (Binders::new(binders, ty.cast(Interner)), p.default.is_some())
1358            }
1359            GenericParamDataRef::ConstParamData(p) => {
1360                let GenericParamId::ConstParamId(id) = id else {
1361                    unreachable!("Unexpected lifetime or type argument")
1362                };
1363
1364                let mut val = p.default.as_ref().map_or_else(
1365                    || unknown_const_as_generic(ctx.db.const_param_ty(id)),
1366                    |c| {
1367                        let param_ty = ctx.lower_ty(p.ty);
1368                        let c = ctx.lower_const(c, param_ty);
1369                        c.cast(Interner)
1370                    },
1371                );
1372                // Each default can only refer to previous parameters, see above.
1373                val = fallback_bound_vars(val, idx);
1374                (Binders::new(binders, val), p.default.is_some())
1375            }
1376            GenericParamDataRef::LifetimeParamData(_) => {
1377                (Binders::new(binders, error_lifetime().cast(Interner)), false)
1378            }
1379        }
1380    }
1381}
1382
1383pub(crate) fn generic_defaults_with_diagnostics_cycle_result(
1384    _db: &dyn HirDatabase,
1385    _def: GenericDefId,
1386) -> (GenericDefaults, Diagnostics) {
1387    (GenericDefaults(None), None)
1388}
1389
1390fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1391    let data = db.function_signature(def);
1392    let resolver = def.resolver(db);
1393    let mut ctx_params = TyLoweringContext::new(
1394        db,
1395        &resolver,
1396        &data.store,
1397        def.into(),
1398        LifetimeElisionKind::for_fn_params(&data),
1399    )
1400    .with_type_param_mode(ParamLoweringMode::Variable);
1401    let params = data.params.iter().map(|&tr| ctx_params.lower_ty(tr));
1402
1403    let ret = match data.ret_type {
1404        Some(ret_type) => {
1405            let mut ctx_ret = TyLoweringContext::new(
1406                db,
1407                &resolver,
1408                &data.store,
1409                def.into(),
1410                LifetimeElisionKind::for_fn_ret(),
1411            )
1412            .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1413            .with_type_param_mode(ParamLoweringMode::Variable);
1414            ctx_ret.lower_ty(ret_type)
1415        }
1416        None => TyKind::Tuple(0, Substitution::empty(Interner)).intern(Interner),
1417    };
1418    let generics = generics(db, def.into());
1419    let sig = CallableSig::from_params_and_return(
1420        params,
1421        ret,
1422        data.is_varargs(),
1423        if data.is_unsafe() { Safety::Unsafe } else { Safety::Safe },
1424        data.abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol),
1425    );
1426    make_binders(db, &generics, sig)
1427}
1428
1429/// Build the declared type of a function. This should not need to look at the
1430/// function body.
1431fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1432    let generics = generics(db, def.into());
1433    let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1434    make_binders(
1435        db,
1436        &generics,
1437        TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(Interner),
1438    )
1439}
1440
1441/// Build the declared type of a const.
1442fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
1443    let data = db.const_signature(def);
1444    let generics = generics(db, def.into());
1445    let resolver = def.resolver(db);
1446    let parent = def.loc(db).container;
1447    let mut ctx = TyLoweringContext::new(
1448        db,
1449        &resolver,
1450        &data.store,
1451        def.into(),
1452        LifetimeElisionKind::for_const(parent),
1453    )
1454    .with_type_param_mode(ParamLoweringMode::Variable);
1455
1456    make_binders(db, &generics, ctx.lower_ty(data.type_ref))
1457}
1458
1459/// Build the declared type of a static.
1460fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
1461    let data = db.static_signature(def);
1462    let resolver = def.resolver(db);
1463    let mut ctx = TyLoweringContext::new(
1464        db,
1465        &resolver,
1466        &data.store,
1467        def.into(),
1468        LifetimeElisionKind::Elided(static_lifetime()),
1469    );
1470
1471    Binders::empty(Interner, ctx.lower_ty(data.type_ref))
1472}
1473
1474fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
1475    let field_tys = db.field_types(def.into());
1476    let params = field_tys.iter().map(|(_, ty)| ty.skip_binders().clone());
1477    let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
1478    Binders::new(
1479        binders,
1480        CallableSig::from_params_and_return(params, ret, false, Safety::Safe, FnAbi::RustCall),
1481    )
1482}
1483
1484/// Build the type of a tuple struct constructor.
1485fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Option<Binders<Ty>> {
1486    let struct_data = def.fields(db);
1487    match struct_data.shape {
1488        FieldsShape::Record => None,
1489        FieldsShape::Unit => Some(type_for_adt(db, def.into())),
1490        FieldsShape::Tuple => {
1491            let generics = generics(db, AdtId::from(def).into());
1492            let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1493            Some(make_binders(
1494                db,
1495                &generics,
1496                TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
1497            ))
1498        }
1499    }
1500}
1501
1502fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
1503    let field_tys = db.field_types(def.into());
1504    let params = field_tys.iter().map(|(_, ty)| ty.skip_binders().clone());
1505    let parent = def.lookup(db).parent;
1506    let (ret, binders) = type_for_adt(db, parent.into()).into_value_and_skipped_binders();
1507    Binders::new(
1508        binders,
1509        CallableSig::from_params_and_return(params, ret, false, Safety::Safe, FnAbi::RustCall),
1510    )
1511}
1512
1513/// Build the type of a tuple enum variant constructor.
1514fn type_for_enum_variant_constructor(
1515    db: &dyn HirDatabase,
1516    def: EnumVariantId,
1517) -> Option<Binders<Ty>> {
1518    let e = def.lookup(db).parent;
1519    match def.fields(db).shape {
1520        FieldsShape::Record => None,
1521        FieldsShape::Unit => Some(type_for_adt(db, e.into())),
1522        FieldsShape::Tuple => {
1523            let generics = generics(db, e.into());
1524            let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1525            Some(make_binders(
1526                db,
1527                &generics,
1528                TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs)
1529                    .intern(Interner),
1530            ))
1531        }
1532    }
1533}
1534
1535#[salsa_macros::tracked(cycle_result = type_for_adt_cycle_result)]
1536fn type_for_adt_tracked(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1537    type_for_adt(db, adt)
1538}
1539
1540fn type_for_adt_cycle_result(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1541    let generics = generics(db, adt.into());
1542    make_binders(db, &generics, TyKind::Error.intern(Interner))
1543}
1544
1545fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1546    let generics = generics(db, adt.into());
1547    let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1548    let ty = TyKind::Adt(crate::AdtId(adt), subst).intern(Interner);
1549    make_binders(db, &generics, ty)
1550}
1551
1552pub(crate) fn type_for_type_alias_with_diagnostics_query(
1553    db: &dyn HirDatabase,
1554    t: TypeAliasId,
1555) -> (Binders<Ty>, Diagnostics) {
1556    let generics = generics(db, t.into());
1557    let type_alias_data = db.type_alias_signature(t);
1558    let mut diags = None;
1559    let inner = if type_alias_data.flags.contains(TypeAliasFlags::IS_EXTERN) {
1560        TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner)
1561    } else {
1562        let resolver = t.resolver(db);
1563        let alias = db.type_alias_signature(t);
1564        let mut ctx = TyLoweringContext::new(
1565            db,
1566            &resolver,
1567            &alias.store,
1568            t.into(),
1569            LifetimeElisionKind::AnonymousReportError,
1570        )
1571        .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1572        .with_type_param_mode(ParamLoweringMode::Variable);
1573        let res = alias
1574            .ty
1575            .map(|type_ref| ctx.lower_ty(type_ref))
1576            .unwrap_or_else(|| TyKind::Error.intern(Interner));
1577        diags = create_diagnostics(ctx.diagnostics);
1578        res
1579    };
1580
1581    (make_binders(db, &generics, inner), diags)
1582}
1583
1584pub(crate) fn type_for_type_alias_with_diagnostics_cycle_result(
1585    db: &dyn HirDatabase,
1586    adt: TypeAliasId,
1587) -> (Binders<Ty>, Diagnostics) {
1588    let generics = generics(db, adt.into());
1589    (make_binders(db, &generics, TyKind::Error.intern(Interner)), None)
1590}
1591
1592#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1593pub enum TyDefId {
1594    BuiltinType(BuiltinType),
1595    AdtId(AdtId),
1596    TypeAliasId(TypeAliasId),
1597}
1598impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
1599
1600#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
1601pub enum ValueTyDefId {
1602    FunctionId(FunctionId),
1603    StructId(StructId),
1604    UnionId(UnionId),
1605    EnumVariantId(EnumVariantId),
1606    ConstId(ConstId),
1607    StaticId(StaticId),
1608}
1609impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
1610
1611impl ValueTyDefId {
1612    pub(crate) fn to_generic_def_id(self, db: &dyn HirDatabase) -> GenericDefId {
1613        match self {
1614            Self::FunctionId(id) => id.into(),
1615            Self::StructId(id) => id.into(),
1616            Self::UnionId(id) => id.into(),
1617            Self::EnumVariantId(var) => var.lookup(db).parent.into(),
1618            Self::ConstId(id) => id.into(),
1619            Self::StaticId(id) => id.into(),
1620        }
1621    }
1622}
1623
1624/// Build the declared type of an item. This depends on the namespace; e.g. for
1625/// `struct Foo(usize)`, we have two types: The type of the struct itself, and
1626/// the constructor function `(usize) -> Foo` which lives in the values
1627/// namespace.
1628pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
1629    match def {
1630        TyDefId::BuiltinType(it) => Binders::empty(Interner, TyBuilder::builtin(it)),
1631        TyDefId::AdtId(it) => type_for_adt_tracked(db, it),
1632        TyDefId::TypeAliasId(it) => db.type_for_type_alias_with_diagnostics(it).0,
1633    }
1634}
1635
1636pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Option<Binders<Ty>> {
1637    match def {
1638        ValueTyDefId::FunctionId(it) => Some(type_for_fn(db, it)),
1639        ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
1640        ValueTyDefId::UnionId(it) => Some(type_for_adt(db, it.into())),
1641        ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
1642        ValueTyDefId::ConstId(it) => Some(type_for_const(db, it)),
1643        ValueTyDefId::StaticId(it) => Some(type_for_static(db, it)),
1644    }
1645}
1646
1647pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> {
1648    db.impl_self_ty_with_diagnostics(impl_id).0
1649}
1650
1651pub(crate) fn impl_self_ty_with_diagnostics_query(
1652    db: &dyn HirDatabase,
1653    impl_id: ImplId,
1654) -> (Binders<Ty>, Diagnostics) {
1655    let impl_data = db.impl_signature(impl_id);
1656    let resolver = impl_id.resolver(db);
1657    let generics = generics(db, impl_id.into());
1658    let mut ctx = TyLoweringContext::new(
1659        db,
1660        &resolver,
1661        &impl_data.store,
1662        impl_id.into(),
1663        LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true },
1664    )
1665    .with_type_param_mode(ParamLoweringMode::Variable);
1666    (
1667        make_binders(db, &generics, ctx.lower_ty(impl_data.self_ty)),
1668        create_diagnostics(ctx.diagnostics),
1669    )
1670}
1671
1672pub(crate) fn impl_self_ty_with_diagnostics_cycle_result(
1673    db: &dyn HirDatabase,
1674    impl_id: ImplId,
1675) -> (Binders<Ty>, Diagnostics) {
1676    let generics = generics(db, impl_id.into());
1677    (make_binders(db, &generics, TyKind::Error.intern(Interner)), None)
1678}
1679
1680pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
1681    db.const_param_ty_with_diagnostics(def).0
1682}
1683
1684// returns None if def is a type arg
1685pub(crate) fn const_param_ty_with_diagnostics_query(
1686    db: &dyn HirDatabase,
1687    def: ConstParamId,
1688) -> (Ty, Diagnostics) {
1689    let (parent_data, store) = db.generic_params_and_store(def.parent());
1690    let data = &parent_data[def.local_id()];
1691    let resolver = def.parent().resolver(db);
1692    let mut ctx = TyLoweringContext::new(
1693        db,
1694        &resolver,
1695        &store,
1696        def.parent(),
1697        LifetimeElisionKind::AnonymousReportError,
1698    );
1699    let ty = match data {
1700        TypeOrConstParamData::TypeParamData(_) => {
1701            never!();
1702            Ty::new(Interner, TyKind::Error)
1703        }
1704        TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(d.ty),
1705    };
1706    (ty, create_diagnostics(ctx.diagnostics))
1707}
1708
1709pub(crate) fn const_param_ty_with_diagnostics_cycle_result(
1710    _: &dyn HirDatabase,
1711    _: crate::db::HirDatabaseData,
1712    _: ConstParamId,
1713) -> (Ty, Diagnostics) {
1714    (TyKind::Error.intern(Interner), None)
1715}
1716
1717pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
1718    db.impl_trait_with_diagnostics(impl_id).map(|it| it.0)
1719}
1720
1721pub(crate) fn impl_trait_with_diagnostics_query(
1722    db: &dyn HirDatabase,
1723    impl_id: ImplId,
1724) -> Option<(Binders<TraitRef>, Diagnostics)> {
1725    let impl_data = db.impl_signature(impl_id);
1726    let resolver = impl_id.resolver(db);
1727    let mut ctx = TyLoweringContext::new(
1728        db,
1729        &resolver,
1730        &impl_data.store,
1731        impl_id.into(),
1732        LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true },
1733    )
1734    .with_type_param_mode(ParamLoweringMode::Variable);
1735    let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
1736    let target_trait = impl_data.target_trait.as_ref()?;
1737    let trait_ref = Binders::new(binders, ctx.lower_trait_ref(target_trait, self_ty)?);
1738    Some((trait_ref, create_diagnostics(ctx.diagnostics)))
1739}
1740
1741pub(crate) fn return_type_impl_traits(
1742    db: &dyn HirDatabase,
1743    def: hir_def::FunctionId,
1744) -> Option<Arc<Binders<ImplTraits>>> {
1745    // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
1746    let data = db.function_signature(def);
1747    let resolver = def.resolver(db);
1748    let mut ctx_ret =
1749        TyLoweringContext::new(db, &resolver, &data.store, def.into(), LifetimeElisionKind::Infer)
1750            .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1751            .with_type_param_mode(ParamLoweringMode::Variable);
1752    if let Some(ret_type) = data.ret_type {
1753        let _ret = ctx_ret.lower_ty(ret_type);
1754    }
1755    let generics = generics(db, def.into());
1756    let return_type_impl_traits =
1757        ImplTraits { impl_traits: ctx_ret.impl_trait_mode.opaque_type_data };
1758    if return_type_impl_traits.impl_traits.is_empty() {
1759        None
1760    } else {
1761        Some(Arc::new(make_binders(db, &generics, return_type_impl_traits)))
1762    }
1763}
1764
1765pub(crate) fn type_alias_impl_traits(
1766    db: &dyn HirDatabase,
1767    def: hir_def::TypeAliasId,
1768) -> Option<Arc<Binders<ImplTraits>>> {
1769    let data = db.type_alias_signature(def);
1770    let resolver = def.resolver(db);
1771    let mut ctx = TyLoweringContext::new(
1772        db,
1773        &resolver,
1774        &data.store,
1775        def.into(),
1776        LifetimeElisionKind::AnonymousReportError,
1777    )
1778    .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1779    .with_type_param_mode(ParamLoweringMode::Variable);
1780    if let Some(type_ref) = data.ty {
1781        let _ty = ctx.lower_ty(type_ref);
1782    }
1783    let type_alias_impl_traits = ImplTraits { impl_traits: ctx.impl_trait_mode.opaque_type_data };
1784    if type_alias_impl_traits.impl_traits.is_empty() {
1785        None
1786    } else {
1787        let generics = generics(db, def.into());
1788        Some(Arc::new(make_binders(db, &generics, type_alias_impl_traits)))
1789    }
1790}
1791
1792pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mutability {
1793    match m {
1794        hir_def::type_ref::Mutability::Shared => Mutability::Not,
1795        hir_def::type_ref::Mutability::Mut => Mutability::Mut,
1796    }
1797}
1798
1799/// Replaces any 'free' `BoundVar`s in `s` by `TyKind::Error` from the perspective of generic
1800/// parameter whose index is `param_index`. A `BoundVar` is free when it appears after the
1801/// generic parameter of `param_index`.
1802fn fallback_bound_vars<T: TypeFoldable<Interner> + HasInterner<Interner = Interner>>(
1803    s: T,
1804    param_index: usize,
1805) -> T {
1806    let is_allowed = |index| (0..param_index).contains(&index);
1807
1808    crate::fold_free_vars(
1809        s,
1810        |bound, binders| {
1811            if bound.index_if_innermost().is_none_or(is_allowed) {
1812                bound.shifted_in_from(binders).to_ty(Interner)
1813            } else {
1814                TyKind::Error.intern(Interner)
1815            }
1816        },
1817        |ty, bound, binders| {
1818            if bound.index_if_innermost().is_none_or(is_allowed) {
1819                bound.shifted_in_from(binders).to_const(Interner, ty)
1820            } else {
1821                unknown_const(ty)
1822            }
1823        },
1824    )
1825}