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