1 //! Methods for lowering the HIR to types. There are two main cases here:
3 //! - Lowering a type reference like `&usize` or `Option<foo::bar::Baz>` to a
4 //! type: The entry point for this is `Ty::from_hir`.
5 //! - Building the type for an item: This happens through the `type_for_def` query.
7 //! This usually involves resolving names, collecting generic arguments etc.
9 cell::{Cell, RefCell, RefMut},
16 cast::Cast, fold::Shift, fold::TypeFoldable, interner::HasInterner, Mutability, Safety,
21 body::{Expander, LowerCtx},
22 builtin_type::BuiltinType,
24 TypeOrConstParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
28 path::{GenericArg, ModPath, Path, PathKind, PathSegment, PathSegments},
29 resolver::{HasResolver, Resolver, TypeNs},
31 ConstScalarOrPath, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef,
33 AdtId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId,
34 HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
35 TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, VariantId,
37 use hir_expand::{name::Name, ExpandResult};
38 use itertools::Either;
39 use la_arena::ArenaMap;
40 use rustc_hash::FxHashSet;
41 use smallvec::SmallVec;
42 use stdx::{impl_from, never};
43 use syntax::{ast, SmolStr};
47 consteval::{intern_const_scalar, path_to_const, unknown_const, unknown_const_as_generic},
51 static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
53 utils::{all_super_trait_refs, associated_type_by_name_including_super_traits, generics},
54 AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, DebruijnIndex, DynTy, FnPointer,
55 FnSig, FnSubst, GenericArgData, ImplTraitId, Interner, ParamKind, PolyFnSig, ProjectionTy,
56 QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits,
57 Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
61 pub struct TyLoweringContext<'a> {
62 pub db: &'a dyn HirDatabase,
63 pub resolver: &'a Resolver,
64 in_binders: DebruijnIndex,
65 /// Note: Conceptually, it's thinkable that we could be in a location where
66 /// some type params should be represented as placeholders, and others
67 /// should be converted to variables. I think in practice, this isn't
68 /// possible currently, so this should be fine for now.
69 pub type_param_mode: ParamLoweringMode,
70 pub impl_trait_mode: ImplTraitLoweringMode,
71 impl_trait_counter: Cell<u16>,
72 /// When turning `impl Trait` into opaque types, we have to collect the
73 /// bounds at the same time to get the IDs correct (without becoming too
74 /// complicated). I don't like using interior mutability (as for the
75 /// counter), but I've tried and failed to make the lifetimes work for
76 /// passing around a `&mut TyLoweringContext`. The core problem is that
77 /// we're grouping the mutable data (the counter and this field) together
78 /// with the immutable context (the references to the DB and resolver).
79 /// Splitting this up would be a possible fix.
80 opaque_type_data: RefCell<Vec<ReturnTypeImplTrait>>,
81 expander: RefCell<Option<Expander>>,
82 /// Tracks types with explicit `?Sized` bounds.
83 pub(crate) unsized_types: RefCell<FxHashSet<Ty>>,
86 impl<'a> TyLoweringContext<'a> {
87 pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver) -> Self {
88 let impl_trait_counter = Cell::new(0);
89 let impl_trait_mode = ImplTraitLoweringMode::Disallowed;
90 let type_param_mode = ParamLoweringMode::Placeholder;
91 let in_binders = DebruijnIndex::INNERMOST;
92 let opaque_type_data = RefCell::new(Vec::new());
101 expander: RefCell::new(None),
102 unsized_types: RefCell::default(),
106 pub fn with_debruijn<T>(
108 debruijn: DebruijnIndex,
109 f: impl FnOnce(&TyLoweringContext<'_>) -> T,
111 let opaque_ty_data_vec = self.opaque_type_data.take();
112 let expander = self.expander.take();
113 let unsized_types = self.unsized_types.take();
115 in_binders: debruijn,
116 impl_trait_counter: Cell::new(self.impl_trait_counter.get()),
117 opaque_type_data: RefCell::new(opaque_ty_data_vec),
118 expander: RefCell::new(expander),
119 unsized_types: RefCell::new(unsized_types),
122 let result = f(&new_ctx);
123 self.impl_trait_counter.set(new_ctx.impl_trait_counter.get());
124 self.opaque_type_data.replace(new_ctx.opaque_type_data.into_inner());
125 self.expander.replace(new_ctx.expander.into_inner());
126 self.unsized_types.replace(new_ctx.unsized_types.into_inner());
130 pub fn with_shifted_in<T>(
132 debruijn: DebruijnIndex,
133 f: impl FnOnce(&TyLoweringContext<'_>) -> T,
135 self.with_debruijn(self.in_binders.shifted_in_from(debruijn), f)
138 pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
139 Self { impl_trait_mode, ..self }
142 pub fn with_type_param_mode(self, type_param_mode: ParamLoweringMode) -> Self {
143 Self { type_param_mode, ..self }
147 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
148 pub enum ImplTraitLoweringMode {
149 /// `impl Trait` gets lowered into an opaque type that doesn't unify with
150 /// anything except itself. This is used in places where values flow 'out',
151 /// i.e. for arguments of the function we're currently checking, and return
152 /// types of functions we're calling.
154 /// `impl Trait` gets lowered into a type variable. Used for argument
155 /// position impl Trait when inside the respective function, since it allows
156 /// us to support that without Chalk.
158 /// `impl Trait` gets lowered into a variable that can unify with some
159 /// type. This is used in places where values flow 'in', i.e. for arguments
160 /// of functions we're calling, and the return type of the function we're
161 /// currently checking.
163 /// `impl Trait` is disallowed and will be an error.
167 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
168 pub enum ParamLoweringMode {
173 impl<'a> TyLoweringContext<'a> {
174 pub fn lower_ty(&self, type_ref: &TypeRef) -> Ty {
175 self.lower_ty_ext(type_ref).0
178 fn generics(&self) -> Generics {
183 .expect("there should be generics if there's a generic param"),
187 pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
189 let ty = match type_ref {
190 TypeRef::Never => TyKind::Never.intern(Interner),
191 TypeRef::Tuple(inner) => {
192 let inner_tys = inner.iter().map(|tr| self.lower_ty(tr));
193 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(Interner, inner_tys))
196 TypeRef::Path(path) => {
197 let (ty, res_) = self.lower_path(path);
201 TypeRef::RawPtr(inner, mutability) => {
202 let inner_ty = self.lower_ty(inner);
203 TyKind::Raw(lower_to_chalk_mutability(*mutability), inner_ty).intern(Interner)
205 TypeRef::Array(inner, len) => {
206 let inner_ty = self.lower_ty(inner);
207 let const_len = const_or_path_to_chalk(
212 self.type_param_mode,
217 TyKind::Array(inner_ty, const_len).intern(Interner)
219 TypeRef::Slice(inner) => {
220 let inner_ty = self.lower_ty(inner);
221 TyKind::Slice(inner_ty).intern(Interner)
223 TypeRef::Reference(inner, _, mutability) => {
224 let inner_ty = self.lower_ty(inner);
225 let lifetime = static_lifetime();
226 TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty)
229 TypeRef::Placeholder => TyKind::Error.intern(Interner),
230 TypeRef::Fn(params, is_varargs) => {
231 let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
232 Substitution::from_iter(Interner, params.iter().map(|(_, tr)| ctx.lower_ty(tr)))
234 TyKind::Function(FnPointer {
235 num_binders: 0, // FIXME lower `for<'a> fn()` correctly
236 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
237 substitution: FnSubst(substs),
241 TypeRef::DynTrait(bounds) => self.lower_dyn_trait(bounds),
242 TypeRef::ImplTrait(bounds) => {
243 match self.impl_trait_mode {
244 ImplTraitLoweringMode::Opaque => {
245 let idx = self.impl_trait_counter.get();
246 self.impl_trait_counter.set(idx + 1);
247 let func = match self.resolver.generic_def() {
248 Some(GenericDefId::FunctionId(f)) => f,
249 _ => panic!("opaque impl trait lowering in non-function"),
252 assert!(idx as usize == self.opaque_type_data.borrow().len());
253 // this dance is to make sure the data is in the right
254 // place even if we encounter more opaque types while
255 // lowering the bounds
256 self.opaque_type_data.borrow_mut().push(ReturnTypeImplTrait {
257 bounds: crate::make_single_type_binders(Vec::new()),
259 // We don't want to lower the bounds inside the binders
260 // we're currently in, because they don't end up inside
261 // those binders. E.g. when we have `impl Trait<impl
262 // OtherTrait<T>>`, the `impl OtherTrait<T>` can't refer
263 // to the self parameter from `impl Trait`, and the
264 // bounds aren't actually stored nested within each
265 // other, but separately. So if the `T` refers to a type
266 // parameter of the outer function, it's just one binder
267 // away instead of two.
268 let actual_opaque_type_data = self
269 .with_debruijn(DebruijnIndex::INNERMOST, |ctx| {
270 ctx.lower_impl_trait(bounds, func)
272 self.opaque_type_data.borrow_mut()[idx as usize] = actual_opaque_type_data;
274 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx);
275 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
276 let generics = generics(self.db.upcast(), func.into());
277 let parameters = generics.bound_vars_subst(self.db, self.in_binders);
278 TyKind::OpaqueType(opaque_ty_id, parameters).intern(Interner)
280 ImplTraitLoweringMode::Param => {
281 let idx = self.impl_trait_counter.get();
282 // FIXME we're probably doing something wrong here
283 self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
284 if let Some(def) = self.resolver.generic_def() {
285 let generics = generics(self.db.upcast(), def);
288 .filter(|(_, data)| {
291 TypeOrConstParamData::TypeParamData(data)
292 if data.provenance == TypeParamProvenance::ArgumentImplTrait
296 .map_or(TyKind::Error, |(id, _)| {
297 TyKind::Placeholder(to_placeholder_idx(self.db, id))
299 param.intern(Interner)
301 TyKind::Error.intern(Interner)
304 ImplTraitLoweringMode::Variable => {
305 let idx = self.impl_trait_counter.get();
306 // FIXME we're probably doing something wrong here
307 self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
314 ) = if let Some(def) = self.resolver.generic_def() {
315 let generics = generics(self.db.upcast(), def);
316 generics.provenance_split()
320 TyKind::BoundVar(BoundVar::new(
322 idx as usize + parent_params + self_params + list_params + const_params,
326 ImplTraitLoweringMode::Disallowed => {
327 // FIXME: report error
328 TyKind::Error.intern(Interner)
332 TypeRef::Macro(macro_call) => {
333 let (mut expander, recursion_start) = {
334 match RefMut::filter_map(self.expander.borrow_mut(), Option::as_mut) {
335 // There already is an expander here, this means we are already recursing
336 Ok(expander) => (expander, false),
337 // No expander was created yet, so we are at the start of the expansion recursion
338 // and therefore have to create an expander.
340 RefMut::map(expander, |it| {
341 it.insert(Expander::new(
344 self.resolver.module(),
352 let macro_call = macro_call.to_node(self.db.upcast());
353 match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
354 Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
355 let ctx = LowerCtx::new(self.db.upcast(), expander.current_file_id());
356 let type_ref = TypeRef::from_ast(&ctx, expanded);
359 let ty = self.lower_ty(&type_ref);
365 .exit(self.db.upcast(), mark);
375 // drop the expander, resetting it to pre-recursion state
377 *self.expander.borrow_mut() = None;
379 ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
381 TypeRef::Error => TyKind::Error.intern(Interner),
386 /// This is only for `generic_predicates_for_param`, where we can't just
387 /// lower the self types of the predicates since that could lead to cycles.
388 /// So we just check here if the `type_ref` resolves to a generic param, and which.
389 fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeOrConstParamId> {
390 let path = match type_ref {
391 TypeRef::Path(path) => path,
394 if path.type_anchor().is_some() {
397 if path.segments().len() > 1 {
401 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
402 Some((it, None)) => it,
406 TypeNs::GenericParam(param_id) => Some(param_id.into()),
411 pub(crate) fn lower_ty_relative_path(
414 // We need the original resolution to lower `Self::AssocTy` correctly
416 remaining_segments: PathSegments<'_>,
417 ) -> (Ty, Option<TypeNs>) {
418 match remaining_segments.len() {
421 // resolve unselected assoc types
422 let segment = remaining_segments.first().unwrap();
423 (self.select_associated_type(res, segment), None)
426 // FIXME report error (ambiguous associated type)
427 (TyKind::Error.intern(Interner), None)
432 pub(crate) fn lower_partly_resolved_path(
435 resolved_segment: PathSegment<'_>,
436 remaining_segments: PathSegments<'_>,
438 ) -> (Ty, Option<TypeNs>) {
439 let ty = match resolution {
440 TypeNs::TraitId(trait_) => {
441 let ty = match remaining_segments.len() {
444 self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None);
445 let segment = remaining_segments.first().unwrap();
448 .trait_data(trait_ref.hir_trait_id())
449 .associated_type_by_name(segment.name);
451 Some(associated_ty) => {
452 // FIXME handle type parameters on the segment
453 TyKind::Alias(AliasTy::Projection(ProjectionTy {
454 associated_ty_id: to_assoc_type_id(associated_ty),
455 substitution: trait_ref.substitution,
460 // FIXME: report error (associated type not found)
461 TyKind::Error.intern(Interner)
466 // Trait object type without dyn; this should be handled in upstream. See
468 stdx::never!("unexpected fully resolved trait path");
469 TyKind::Error.intern(Interner)
472 // FIXME report error (ambiguous associated type)
473 TyKind::Error.intern(Interner)
478 TypeNs::GenericParam(param_id) => {
479 let generics = generics(
481 self.resolver.generic_def().expect("generics in scope"),
483 match self.type_param_mode {
484 ParamLoweringMode::Placeholder => {
485 TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into()))
487 ParamLoweringMode::Variable => {
488 let idx = match generics.param_idx(param_id.into()) {
490 never!("no matching generics");
491 return (TyKind::Error.intern(Interner), None);
496 TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
501 TypeNs::SelfType(impl_id) => {
502 let generics = generics(self.db.upcast(), impl_id.into());
503 let substs = match self.type_param_mode {
504 ParamLoweringMode::Placeholder => generics.placeholder_subst(self.db),
505 ParamLoweringMode::Variable => {
506 generics.bound_vars_subst(self.db, self.in_binders)
509 self.db.impl_self_ty(impl_id).substitute(Interner, &substs)
511 TypeNs::AdtSelfType(adt) => {
512 let generics = generics(self.db.upcast(), adt.into());
513 let substs = match self.type_param_mode {
514 ParamLoweringMode::Placeholder => generics.placeholder_subst(self.db),
515 ParamLoweringMode::Variable => {
516 generics.bound_vars_subst(self.db, self.in_binders)
519 self.db.ty(adt.into()).substitute(Interner, &substs)
522 TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args),
523 TypeNs::BuiltinType(it) => {
524 self.lower_path_inner(resolved_segment, it.into(), infer_args)
526 TypeNs::TypeAliasId(it) => {
527 self.lower_path_inner(resolved_segment, it.into(), infer_args)
529 // FIXME: report error
530 TypeNs::EnumVariantId(_) => return (TyKind::Error.intern(Interner), None),
532 self.lower_ty_relative_path(ty, Some(resolution), remaining_segments)
535 pub(crate) fn lower_path(&self, path: &Path) -> (Ty, Option<TypeNs>) {
536 // Resolve the path (in type namespace)
537 if let Some(type_ref) = path.type_anchor() {
538 let (ty, res) = self.lower_ty_ext(type_ref);
539 return self.lower_ty_relative_path(ty, res, path.segments());
542 let (resolution, remaining_index) =
543 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
545 None => return (TyKind::Error.intern(Interner), None),
548 if matches!(resolution, TypeNs::TraitId(_)) && remaining_index.is_none() {
549 // trait object type without dyn
550 let bound = TypeBound::Path(path.clone(), TraitBoundModifier::None);
551 let ty = self.lower_dyn_trait(&[Interned::new(bound)]);
555 let (resolved_segment, remaining_segments) = match remaining_index {
557 path.segments().last().expect("resolved path has at least one element"),
560 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)),
562 self.lower_partly_resolved_path(resolution, resolved_segment, remaining_segments, false)
565 fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
566 let (def, res) = match (self.resolver.generic_def(), res) {
567 (Some(def), Some(res)) => (def, res),
568 _ => return TyKind::Error.intern(Interner),
570 let ty = named_associated_type_shorthand_candidates(
574 Some(segment.name.clone()),
575 move |name, t, associated_ty| {
576 if name == segment.name {
577 let substs = match self.type_param_mode {
578 ParamLoweringMode::Placeholder => {
579 // if we're lowering to placeholders, we have to put
581 let generics = generics(
585 .expect("there should be generics if there's a generic param"),
587 let s = generics.placeholder_subst(self.db);
588 s.apply(t.substitution.clone(), Interner)
590 ParamLoweringMode::Variable => t.substitution.clone(),
592 // We need to shift in the bound vars, since
593 // associated_type_shorthand_candidates does not do that
594 let substs = substs.shifted_in_from(Interner, self.in_binders);
595 // FIXME handle type parameters on the segment
597 TyKind::Alias(AliasTy::Projection(ProjectionTy {
598 associated_ty_id: to_assoc_type_id(associated_ty),
599 substitution: substs,
609 ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
614 segment: PathSegment<'_>,
618 let generic_def = match typeable {
619 TyDefId::BuiltinType(_) => None,
620 TyDefId::AdtId(it) => Some(it.into()),
621 TyDefId::TypeAliasId(it) => Some(it.into()),
623 let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None);
624 self.db.ty(typeable).substitute(Interner, &substs)
627 /// Collect generic arguments from a path into a `Substs`. See also
628 /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
629 pub(super) fn substs_from_path(
632 // Note that we don't call `db.value_type(resolved)` here,
633 // `ValueTyDefId` is just a convenient way to pass generics and
634 // special-case enum variants
635 resolved: ValueTyDefId,
638 let last = path.segments().last().expect("path should have at least one segment");
639 let (segment, generic_def) = match resolved {
640 ValueTyDefId::FunctionId(it) => (last, Some(it.into())),
641 ValueTyDefId::StructId(it) => (last, Some(it.into())),
642 ValueTyDefId::UnionId(it) => (last, Some(it.into())),
643 ValueTyDefId::ConstId(it) => (last, Some(it.into())),
644 ValueTyDefId::StaticId(_) => (last, None),
645 ValueTyDefId::EnumVariantId(var) => {
646 // the generic args for an enum variant may be either specified
647 // on the segment referring to the enum, or on the segment
648 // referring to the variant. So `Option::<T>::None` and
649 // `Option::None::<T>` are both allowed (though the former is
650 // preferred). See also `def_ids_for_path_segments` in rustc.
651 let len = path.segments().len();
652 let penultimate = len.checked_sub(2).and_then(|idx| path.segments().get(idx));
653 let segment = match penultimate {
654 Some(segment) if segment.args_and_bindings.is_some() => segment,
657 (segment, Some(var.parent.into()))
660 self.substs_from_path_segment(segment, generic_def, infer_args, None)
663 fn substs_from_path_segment(
665 segment: PathSegment<'_>,
666 def_generic: Option<GenericDefId>,
668 explicit_self_ty: Option<Ty>,
670 let mut substs = Vec::new();
671 let def_generics = if let Some(def) = def_generic {
672 generics(self.db.upcast(), def)
674 return Substitution::empty(Interner);
676 let (parent_params, self_params, type_params, const_params, impl_trait_params) =
677 def_generics.provenance_split();
679 parent_params + self_params + type_params + const_params + impl_trait_params;
681 let ty_error = GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner);
683 let mut def_generic_iter = def_generics.iter_id();
685 for _ in 0..parent_params {
686 if let Some(eid) = def_generic_iter.next() {
688 Either::Left(_) => substs.push(ty_error.clone()),
689 Either::Right(x) => {
690 substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
696 let fill_self_params = || {
697 for x in explicit_self_ty
699 .map(|x| GenericArgData::Ty(x).intern(Interner))
700 .chain(iter::repeat(ty_error.clone()))
703 if let Some(id) = def_generic_iter.next() {
704 assert!(id.is_left());
709 let mut had_explicit_args = false;
711 if let Some(generic_args) = &segment.args_and_bindings {
712 if !generic_args.has_self_type {
715 let expected_num = if generic_args.has_self_type {
716 self_params + type_params + const_params
718 type_params + const_params
720 let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
721 // if args are provided, it should be all of them, but we can't rely on that
722 for arg in generic_args
725 .filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
729 if let Some(id) = def_generic_iter.next() {
730 if let Some(x) = generic_arg_to_chalk(
735 |_, type_ref| self.lower_ty(type_ref),
737 const_or_path_to_chalk(
742 self.type_param_mode,
748 had_explicit_args = true;
751 // we just filtered them out
752 never!("Unexpected lifetime argument");
760 // handle defaults. In expression or pattern path segments without
761 // explicitly specified type arguments, missing type arguments are inferred
762 // (i.e. defaults aren't used).
763 if !infer_args || had_explicit_args {
764 if let Some(def_generic) = def_generic {
765 let defaults = self.db.generic_defaults(def_generic);
766 assert_eq!(total_len, defaults.len());
768 for default_ty in defaults.iter().skip(substs.len()) {
769 // each default can depend on the previous parameters
770 let substs_so_far = Substitution::from_iter(Interner, substs.clone());
771 if let Some(_id) = def_generic_iter.next() {
772 substs.push(default_ty.clone().substitute(Interner, &substs_so_far));
778 // add placeholders for args that were not provided
779 // FIXME: emit diagnostics in contexts where this is not allowed
780 for eid in def_generic_iter {
782 Either::Left(_) => substs.push(ty_error.clone()),
783 Either::Right(x) => {
784 substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
788 // If this assert fails, it means you pushed into subst but didn't call .next() of def_generic_iter
789 assert_eq!(substs.len(), total_len);
791 Substitution::from_iter(Interner, substs)
794 fn lower_trait_ref_from_path(
797 explicit_self_ty: Option<Ty>,
798 ) -> Option<TraitRef> {
800 match self.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), path.mod_path())? {
801 TypeNs::TraitId(tr) => tr,
804 let segment = path.segments().last().expect("path should have at least one segment");
805 Some(self.lower_trait_ref_from_resolved_path(resolved, segment, explicit_self_ty))
808 pub(crate) fn lower_trait_ref_from_resolved_path(
811 segment: PathSegment<'_>,
812 explicit_self_ty: Option<Ty>,
814 let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
815 TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
820 trait_ref: &HirTraitRef,
821 explicit_self_ty: Option<Ty>,
822 ) -> Option<TraitRef> {
823 self.lower_trait_ref_from_path(&trait_ref.path, explicit_self_ty)
826 fn trait_ref_substs_from_path(
828 segment: PathSegment<'_>,
830 explicit_self_ty: Option<Ty>,
832 self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
835 pub(crate) fn lower_where_predicate(
837 where_predicate: &'a WherePredicate,
838 ignore_bindings: bool,
839 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
840 match where_predicate {
841 WherePredicate::ForLifetime { target, bound, .. }
842 | WherePredicate::TypeBound { target, bound } => {
843 let self_ty = match target {
844 WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
845 WherePredicateTypeTarget::TypeOrConstParam(param_id) => {
846 let generic_def = self.resolver.generic_def().expect("generics in scope");
847 let generics = generics(self.db.upcast(), generic_def);
848 let param_id = hir_def::TypeOrConstParamId {
852 let placeholder = to_placeholder_idx(self.db, param_id);
853 match self.type_param_mode {
854 ParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder),
855 ParamLoweringMode::Variable => {
856 let idx = generics.param_idx(param_id).expect("matching generics");
857 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
863 self.lower_type_bound(bound, self_ty, ignore_bindings)
867 WherePredicate::Lifetime { .. } => vec![].into_iter(),
871 pub(crate) fn lower_type_bound(
873 bound: &'a TypeBound,
875 ignore_bindings: bool,
876 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
877 let mut bindings = None;
878 let trait_ref = match bound {
879 TypeBound::Path(path, TraitBoundModifier::None) => {
880 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
884 // ignore `T: Drop` or `T: Destruct` bounds.
885 // - `T: ~const Drop` has a special meaning in Rust 1.61 that we don't implement.
886 // (So ideally, we'd only ignore `~const Drop` here)
887 // - `Destruct` impls are built-in in 1.62 (current nightlies as of 08-04-2022), so until
888 // the builtin impls are supported by Chalk, we ignore them here.
889 if let Some(lang) = lang_attr(self.db.upcast(), tr.hir_trait_id()) {
890 if lang == "drop" || lang == "destruct" {
896 .map(WhereClause::Implemented)
897 .map(crate::wrap_empty_binders)
899 TypeBound::Path(path, TraitBoundModifier::Maybe) => {
900 let sized_trait = self
902 .lang_item(self.resolver.krate(), SmolStr::new_inline("sized"))
903 .and_then(|lang_item| lang_item.as_trait());
904 // Don't lower associated type bindings as the only possible relaxed trait bound
905 // `?Sized` has no of them.
906 // If we got another trait here ignore the bound completely.
908 .lower_trait_ref_from_path(path, Some(self_ty.clone()))
909 .map(|trait_ref| trait_ref.hir_trait_id());
910 if trait_id == sized_trait {
911 self.unsized_types.borrow_mut().insert(self_ty);
915 TypeBound::ForLifetime(_, path) => {
916 // FIXME Don't silently drop the hrtb lifetimes here
917 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
918 bindings.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
920 TypeBound::Lifetime(_) => None,
921 TypeBound::Error => None,
923 trait_ref.into_iter().chain(
926 .filter(move |_| !ignore_bindings)
927 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)),
931 fn assoc_type_bindings_from_type_bound(
933 bound: &'a TypeBound,
935 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
936 let last_segment = match bound {
937 TypeBound::Path(path, TraitBoundModifier::None) | TypeBound::ForLifetime(_, path) => {
938 path.segments().last()
940 TypeBound::Path(_, TraitBoundModifier::Maybe)
942 | TypeBound::Lifetime(_) => None,
946 .filter_map(|segment| segment.args_and_bindings)
947 .flat_map(|args_and_bindings| &args_and_bindings.bindings)
948 .flat_map(move |binding| {
949 let found = associated_type_by_name_including_super_traits(
954 let (super_trait_ref, associated_ty) = match found {
955 None => return SmallVec::new(),
958 let projection_ty = ProjectionTy {
959 associated_ty_id: to_assoc_type_id(associated_ty),
960 substitution: super_trait_ref.substitution,
962 let mut preds: SmallVec<[_; 1]> = SmallVec::with_capacity(
963 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
965 if let Some(type_ref) = &binding.type_ref {
966 let ty = self.lower_ty(type_ref);
968 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
969 preds.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
971 for bound in &binding.bounds {
972 preds.extend(self.lower_type_bound(
974 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(Interner),
982 fn lower_dyn_trait(&self, bounds: &[Interned<TypeBound>]) -> Ty {
983 let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
984 let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
985 QuantifiedWhereClauses::from_iter(
987 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
990 let bounds = crate::make_single_type_binders(bounds);
991 TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
996 bounds: &[Interned<TypeBound>],
998 ) -> ReturnTypeImplTrait {
999 cov_mark::hit!(lower_rpit);
1000 let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
1001 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
1002 let mut predicates: Vec<_> = bounds
1004 .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
1007 if !ctx.unsized_types.borrow().contains(&self_ty) {
1008 let krate = func.lookup(ctx.db.upcast()).module(ctx.db.upcast()).krate();
1009 let sized_trait = ctx
1011 .lang_item(krate, SmolStr::new_inline("sized"))
1012 .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1013 let sized_clause = sized_trait.map(|trait_id| {
1014 let clause = WhereClause::Implemented(TraitRef {
1016 substitution: Substitution::from1(Interner, self_ty.clone()),
1018 crate::wrap_empty_binders(clause)
1020 predicates.extend(sized_clause.into_iter());
1021 predicates.shrink_to_fit();
1025 ReturnTypeImplTrait { bounds: crate::make_single_type_binders(predicates) }
1029 fn count_impl_traits(type_ref: &TypeRef) -> usize {
1031 type_ref.walk(&mut |type_ref| {
1032 if matches!(type_ref, TypeRef::ImplTrait(_)) {
1039 /// Build the signature of a callable item (function, struct or enum variant).
1040 pub(crate) fn callable_item_sig(db: &dyn HirDatabase, def: CallableDefId) -> PolyFnSig {
1042 CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f),
1043 CallableDefId::StructId(s) => fn_sig_for_struct_constructor(db, s),
1044 CallableDefId::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e),
1048 pub fn associated_type_shorthand_candidates<R>(
1049 db: &dyn HirDatabase,
1052 cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
1054 named_associated_type_shorthand_candidates(db, def, res, None, cb)
1057 fn named_associated_type_shorthand_candidates<R>(
1058 db: &dyn HirDatabase,
1059 // If the type parameter is defined in an impl and we're in a method, there
1060 // might be additional where clauses to consider
1063 assoc_name: Option<Name>,
1064 mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
1066 let mut search = |t| {
1067 for t in all_super_trait_refs(db, t) {
1068 let data = db.trait_data(t.hir_trait_id());
1070 for (name, assoc_id) in &data.items {
1071 if let AssocItemId::TypeAliasId(alias) = assoc_id {
1072 if let Some(result) = cb(name, &t, *alias) {
1073 return Some(result);
1082 TypeNs::SelfType(impl_id) => search(
1083 // we're _in_ the impl -- the binders get added back later. Correct,
1084 // but it would be nice to make this more explicit
1085 db.impl_trait(impl_id)?.into_value_and_skipped_binders().0,
1087 TypeNs::GenericParam(param_id) => {
1088 let predicates = db.generic_predicates_for_param(def, param_id.into(), assoc_name);
1089 let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
1090 // FIXME: how to correctly handle higher-ranked bounds here?
1091 WhereClause::Implemented(tr) => search(
1093 .shifted_out_to(Interner, DebruijnIndex::ONE)
1094 .expect("FIXME unexpected higher-ranked trait bound"),
1098 if let Some(_) = res {
1101 // Handle `Self::Type` referring to own associated type in trait definitions
1102 if let GenericDefId::TraitId(trait_id) = param_id.parent() {
1103 let generics = generics(db.upcast(), trait_id.into());
1104 if generics.params.type_or_consts[param_id.local_id()].is_trait_self() {
1105 let trait_ref = TyBuilder::trait_ref(db, trait_id)
1106 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
1108 return search(trait_ref);
1117 /// Build the type of all specific fields of a struct or enum variant.
1118 pub(crate) fn field_types_query(
1119 db: &dyn HirDatabase,
1120 variant_id: VariantId,
1121 ) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> {
1122 let var_data = variant_id.variant_data(db.upcast());
1123 let (resolver, def): (_, GenericDefId) = match variant_id {
1124 VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()),
1125 VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()),
1126 VariantId::EnumVariantId(it) => (it.parent.resolver(db.upcast()), it.parent.into()),
1128 let generics = generics(db.upcast(), def);
1129 let mut res = ArenaMap::default();
1131 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1132 for (field_id, field_data) in var_data.fields().iter() {
1133 res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref)));
1138 /// This query exists only to be used when resolving short-hand associated types
1141 /// See the analogous query in rustc and its comment:
1142 /// <https://github.com/rust-lang/rust/blob/9150f844e2624eb013ec78ca08c1d416e6644026/src/librustc_typeck/astconv.rs#L46>
1143 /// This is a query mostly to handle cycles somewhat gracefully; e.g. the
1144 /// following bounds are disallowed: `T: Foo<U::Item>, U: Foo<T::Item>`, but
1145 /// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
1146 pub(crate) fn generic_predicates_for_param_query(
1147 db: &dyn HirDatabase,
1149 param_id: TypeOrConstParamId,
1150 assoc_name: Option<Name>,
1151 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1152 let resolver = def.resolver(db.upcast());
1154 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1155 let generics = generics(db.upcast(), def);
1156 let mut predicates: Vec<_> = resolver
1157 .where_predicates_in_scope()
1158 // we have to filter out all other predicates *first*, before attempting to lower them
1159 .filter(|pred| match pred {
1160 WherePredicate::ForLifetime { target, bound, .. }
1161 | WherePredicate::TypeBound { target, bound, .. } => {
1163 WherePredicateTypeTarget::TypeRef(type_ref) => {
1164 if ctx.lower_ty_only_param(type_ref) != Some(param_id) {
1168 &WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
1169 let target_id = TypeOrConstParamId { parent: def, local_id };
1170 if target_id != param_id {
1177 TypeBound::ForLifetime(_, path) | TypeBound::Path(path, _) => {
1178 // Only lower the bound if the trait could possibly define the associated
1179 // type we're looking for.
1181 let assoc_name = match &assoc_name {
1183 None => return true,
1185 let tr = match resolver
1186 .resolve_path_in_type_ns_fully(db.upcast(), path.mod_path())
1188 Some(TypeNs::TraitId(tr)) => tr,
1192 all_super_traits(db.upcast(), tr).iter().any(|tr| {
1193 db.trait_data(*tr).items.iter().any(|(name, item)| {
1194 matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name
1198 TypeBound::Lifetime(_) | TypeBound::Error => false,
1201 WherePredicate::Lifetime { .. } => false,
1204 ctx.lower_where_predicate(pred, true).map(|p| make_binders(db, &generics, p))
1208 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1209 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1210 let implicitly_sized_predicates =
1211 implicitly_sized_clauses(db, param_id.parent, &explicitly_unsized_tys, &subst, &resolver)
1212 .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1213 predicates.extend(implicitly_sized_predicates);
1217 pub(crate) fn generic_predicates_for_param_recover(
1218 _db: &dyn HirDatabase,
1220 _def: &GenericDefId,
1221 _param_id: &TypeOrConstParamId,
1222 _assoc_name: &Option<Name>,
1223 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1227 pub(crate) fn trait_environment_query(
1228 db: &dyn HirDatabase,
1230 ) -> Arc<TraitEnvironment> {
1231 let resolver = def.resolver(db.upcast());
1233 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Placeholder);
1234 let mut traits_in_scope = Vec::new();
1235 let mut clauses = Vec::new();
1236 for pred in resolver.where_predicates_in_scope() {
1237 for pred in ctx.lower_where_predicate(pred, false) {
1238 if let WhereClause::Implemented(tr) = &pred.skip_binders() {
1239 traits_in_scope.push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id()));
1241 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1242 clauses.push(program_clause.into_from_env_clause(Interner));
1246 let container: Option<ItemContainerId> = match def {
1247 // FIXME: is there a function for this?
1248 GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
1249 GenericDefId::AdtId(_) => None,
1250 GenericDefId::TraitId(_) => None,
1251 GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container),
1252 GenericDefId::ImplId(_) => None,
1253 GenericDefId::EnumVariantId(_) => None,
1254 GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container),
1256 if let Some(ItemContainerId::TraitId(trait_id)) = container {
1257 // add `Self: Trait<T1, T2, ...>` to the environment in trait
1258 // function default implementations (and speculative code
1259 // inside consts or type aliases)
1260 cov_mark::hit!(trait_self_implements_self);
1261 let substs = TyBuilder::placeholder_subst(db, trait_id);
1262 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
1263 let pred = WhereClause::Implemented(trait_ref);
1264 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1265 clauses.push(program_clause.into_from_env_clause(Interner));
1268 let subst = generics(db.upcast(), def).placeholder_subst(db);
1269 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1270 let implicitly_sized_clauses =
1271 implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver).map(|pred| {
1272 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1273 program_clause.into_from_env_clause(Interner)
1275 clauses.extend(implicitly_sized_clauses);
1277 let krate = def.module(db.upcast()).krate();
1279 let env = chalk_ir::Environment::new(Interner).add_clauses(Interner, clauses);
1281 Arc::new(TraitEnvironment { krate, traits_from_clauses: traits_in_scope, env })
1284 /// Resolve the where clause(s) of an item with generics.
1285 pub(crate) fn generic_predicates_query(
1286 db: &dyn HirDatabase,
1288 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1289 let resolver = def.resolver(db.upcast());
1291 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1292 let generics = generics(db.upcast(), def);
1294 let mut predicates = resolver
1295 .where_predicates_in_scope()
1297 ctx.lower_where_predicate(pred, false).map(|p| make_binders(db, &generics, p))
1299 .collect::<Vec<_>>();
1301 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1302 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1303 let implicitly_sized_predicates =
1304 implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver)
1305 .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1306 predicates.extend(implicitly_sized_predicates);
1310 /// Generate implicit `: Sized` predicates for all generics that has no `?Sized` bound.
1311 /// Exception is Self of a trait def.
1312 fn implicitly_sized_clauses<'a>(
1313 db: &dyn HirDatabase,
1315 explicitly_unsized_tys: &'a FxHashSet<Ty>,
1316 substitution: &'a Substitution,
1317 resolver: &Resolver,
1318 ) -> impl Iterator<Item = WhereClause> + 'a {
1319 let is_trait_def = matches!(def, GenericDefId::TraitId(..));
1320 let generic_args = &substitution.as_slice(Interner)[is_trait_def as usize..];
1321 let sized_trait = db
1322 .lang_item(resolver.krate(), SmolStr::new_inline("sized"))
1323 .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1325 sized_trait.into_iter().flat_map(move |sized_trait| {
1326 let implicitly_sized_tys = generic_args
1328 .filter_map(|generic_arg| generic_arg.ty(Interner))
1329 .filter(move |&self_ty| !explicitly_unsized_tys.contains(self_ty));
1330 implicitly_sized_tys.map(move |self_ty| {
1331 WhereClause::Implemented(TraitRef {
1332 trait_id: sized_trait,
1333 substitution: Substitution::from1(Interner, self_ty.clone()),
1339 /// Resolve the default type params from generics
1340 pub(crate) fn generic_defaults_query(
1341 db: &dyn HirDatabase,
1343 ) -> Arc<[Binders<chalk_ir::GenericArg<Interner>>]> {
1344 let resolver = def.resolver(db.upcast());
1346 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1347 let generic_params = generics(db.upcast(), def);
1349 let defaults = generic_params
1352 .map(|(idx, (id, p))| {
1354 TypeOrConstParamData::TypeParamData(p) => p,
1355 TypeOrConstParamData::ConstParamData(_) => {
1356 // FIXME: implement const generic defaults
1357 let val = unknown_const_as_generic(
1358 db.const_param_ty(ConstParamId::from_unchecked(id)),
1360 return crate::make_binders_with_count(db, idx, &generic_params, val);
1364 p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
1366 // Each default can only refer to previous parameters.
1367 // type variable default referring to parameter coming
1368 // after it. This is forbidden (FIXME: report
1370 ty = fallback_bound_vars(ty, idx);
1371 let val = GenericArgData::Ty(ty).intern(Interner);
1372 crate::make_binders_with_count(db, idx, &generic_params, val)
1379 pub(crate) fn generic_defaults_recover(
1380 db: &dyn HirDatabase,
1383 ) -> Arc<[Binders<crate::GenericArg>]> {
1384 let generic_params = generics(db.upcast(), *def);
1385 // FIXME: this code is not covered in tests.
1386 // we still need one default per parameter
1387 let defaults = generic_params
1390 .map(|(count, id)| {
1391 let val = match id {
1392 itertools::Either::Left(_) => {
1393 GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1395 itertools::Either::Right(id) => unknown_const_as_generic(db.const_param_ty(id)),
1397 crate::make_binders_with_count(db, count, &generic_params, val)
1404 fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1405 let data = db.function_data(def);
1406 let resolver = def.resolver(db.upcast());
1407 let ctx_params = TyLoweringContext::new(db, &resolver)
1408 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
1409 .with_type_param_mode(ParamLoweringMode::Variable);
1410 let params = data.params.iter().map(|(_, tr)| ctx_params.lower_ty(tr)).collect::<Vec<_>>();
1411 let ctx_ret = TyLoweringContext::new(db, &resolver)
1412 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1413 .with_type_param_mode(ParamLoweringMode::Variable);
1414 let ret = ctx_ret.lower_ty(&data.ret_type);
1415 let generics = generics(db.upcast(), def.into());
1416 let sig = CallableSig::from_params_and_return(params, ret, data.is_varargs());
1417 make_binders(db, &generics, sig)
1420 /// Build the declared type of a function. This should not need to look at the
1422 fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1423 let generics = generics(db.upcast(), def.into());
1424 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1428 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(Interner),
1432 /// Build the declared type of a const.
1433 fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
1434 let data = db.const_data(def);
1435 let generics = generics(db.upcast(), def.into());
1436 let resolver = def.resolver(db.upcast());
1438 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1440 make_binders(db, &generics, ctx.lower_ty(&data.type_ref))
1443 /// Build the declared type of a static.
1444 fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
1445 let data = db.static_data(def);
1446 let resolver = def.resolver(db.upcast());
1447 let ctx = TyLoweringContext::new(db, &resolver);
1449 Binders::empty(Interner, ctx.lower_ty(&data.type_ref))
1452 fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
1453 let struct_data = db.struct_data(def);
1454 let fields = struct_data.variant_data.fields();
1455 let resolver = def.resolver(db.upcast());
1457 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1458 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1459 let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
1460 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1463 /// Build the type of a tuple struct constructor.
1464 fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<Ty> {
1465 let struct_data = db.struct_data(def);
1466 if let StructKind::Unit = struct_data.variant_data.kind() {
1467 return type_for_adt(db, def.into());
1469 let generics = generics(db.upcast(), def.into());
1470 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1474 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
1478 fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
1479 let enum_data = db.enum_data(def.parent);
1480 let var_data = &enum_data.variants[def.local_id];
1481 let fields = var_data.variant_data.fields();
1482 let resolver = def.parent.resolver(db.upcast());
1484 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1485 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1486 let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
1487 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1490 /// Build the type of a tuple enum variant constructor.
1491 fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> Binders<Ty> {
1492 let enum_data = db.enum_data(def.parent);
1493 let var_data = &enum_data.variants[def.local_id].variant_data;
1494 if let StructKind::Unit = var_data.kind() {
1495 return type_for_adt(db, def.parent.into());
1497 let generics = generics(db.upcast(), def.parent.into());
1498 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1502 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(Interner),
1506 fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1507 let generics = generics(db.upcast(), adt.into());
1508 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1509 let ty = TyKind::Adt(crate::AdtId(adt), subst).intern(Interner);
1510 make_binders(db, &generics, ty)
1513 fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1514 let generics = generics(db.upcast(), t.into());
1515 let resolver = t.resolver(db.upcast());
1517 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1518 if db.type_alias_data(t).is_extern {
1519 Binders::empty(Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner))
1521 let type_ref = &db.type_alias_data(t).type_ref;
1522 let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
1523 make_binders(db, &generics, inner)
1527 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1528 pub enum CallableDefId {
1529 FunctionId(FunctionId),
1531 EnumVariantId(EnumVariantId),
1533 impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
1535 impl CallableDefId {
1536 pub fn krate(self, db: &dyn HirDatabase) -> CrateId {
1537 let db = db.upcast();
1539 CallableDefId::FunctionId(f) => f.lookup(db).module(db),
1540 CallableDefId::StructId(s) => s.lookup(db).container,
1541 CallableDefId::EnumVariantId(e) => e.parent.lookup(db).container,
1547 impl From<CallableDefId> for GenericDefId {
1548 fn from(def: CallableDefId) -> GenericDefId {
1550 CallableDefId::FunctionId(f) => f.into(),
1551 CallableDefId::StructId(s) => s.into(),
1552 CallableDefId::EnumVariantId(e) => e.into(),
1557 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1559 BuiltinType(BuiltinType),
1561 TypeAliasId(TypeAliasId),
1563 impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
1565 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1566 pub enum ValueTyDefId {
1567 FunctionId(FunctionId),
1570 EnumVariantId(EnumVariantId),
1574 impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
1576 /// Build the declared type of an item. This depends on the namespace; e.g. for
1577 /// `struct Foo(usize)`, we have two types: The type of the struct itself, and
1578 /// the constructor function `(usize) -> Foo` which lives in the values
1580 pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
1582 TyDefId::BuiltinType(it) => Binders::empty(Interner, TyBuilder::builtin(it)),
1583 TyDefId::AdtId(it) => type_for_adt(db, it),
1584 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
1588 pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> {
1589 let generics = match *def {
1590 TyDefId::BuiltinType(_) => return Binders::empty(Interner, TyKind::Error.intern(Interner)),
1591 TyDefId::AdtId(it) => generics(db.upcast(), it.into()),
1592 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()),
1594 make_binders(db, &generics, TyKind::Error.intern(Interner))
1597 pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
1599 ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
1600 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
1601 ValueTyDefId::UnionId(it) => type_for_adt(db, it.into()),
1602 ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
1603 ValueTyDefId::ConstId(it) => type_for_const(db, it),
1604 ValueTyDefId::StaticId(it) => type_for_static(db, it),
1608 pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> {
1609 let impl_loc = impl_id.lookup(db.upcast());
1610 let impl_data = db.impl_data(impl_id);
1611 let resolver = impl_id.resolver(db.upcast());
1612 let _cx = stdx::panic_context::enter(format!(
1613 "impl_self_ty_query({:?} -> {:?} -> {:?})",
1614 impl_id, impl_loc, impl_data
1616 let generics = generics(db.upcast(), impl_id.into());
1618 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1619 make_binders(db, &generics, ctx.lower_ty(&impl_data.self_ty))
1622 // returns None if def is a type arg
1623 pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
1624 let parent_data = db.generic_params(def.parent());
1625 let data = &parent_data.type_or_consts[def.local_id()];
1626 let resolver = def.parent().resolver(db.upcast());
1627 let ctx = TyLoweringContext::new(db, &resolver);
1629 TypeOrConstParamData::TypeParamData(_) => {
1631 Ty::new(Interner, TyKind::Error)
1633 TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(&d.ty),
1637 pub(crate) fn impl_self_ty_recover(
1638 db: &dyn HirDatabase,
1642 let generics = generics(db.upcast(), (*impl_id).into());
1643 make_binders(db, &generics, TyKind::Error.intern(Interner))
1646 pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
1647 let impl_loc = impl_id.lookup(db.upcast());
1648 let impl_data = db.impl_data(impl_id);
1649 let resolver = impl_id.resolver(db.upcast());
1650 let _cx = stdx::panic_context::enter(format!(
1651 "impl_trait_query({:?} -> {:?} -> {:?})",
1652 impl_id, impl_loc, impl_data
1655 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1656 let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
1657 let target_trait = impl_data.target_trait.as_ref()?;
1658 Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
1661 pub(crate) fn return_type_impl_traits(
1662 db: &dyn HirDatabase,
1663 def: hir_def::FunctionId,
1664 ) -> Option<Arc<Binders<ReturnTypeImplTraits>>> {
1665 // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
1666 let data = db.function_data(def);
1667 let resolver = def.resolver(db.upcast());
1668 let ctx_ret = TyLoweringContext::new(db, &resolver)
1669 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1670 .with_type_param_mode(ParamLoweringMode::Variable);
1671 let _ret = (&ctx_ret).lower_ty(&data.ret_type);
1672 let generics = generics(db.upcast(), def.into());
1673 let return_type_impl_traits =
1674 ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() };
1675 if return_type_impl_traits.impl_traits.is_empty() {
1678 Some(Arc::new(make_binders(db, &generics, return_type_impl_traits)))
1682 pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mutability {
1684 hir_def::type_ref::Mutability::Shared => Mutability::Not,
1685 hir_def::type_ref::Mutability::Mut => Mutability::Mut,
1689 /// Checks if the provided generic arg matches its expected kind, then lower them via
1690 /// provided closures. Use unknown if there was kind mismatch.
1692 /// Returns `Some` of the lowered generic arg. `None` if the provided arg is a lifetime.
1693 pub(crate) fn generic_arg_to_chalk<'a, T>(
1694 db: &dyn HirDatabase,
1695 kind_id: Either<TypeParamId, ConstParamId>,
1696 arg: &'a GenericArg,
1698 for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a,
1699 for_const: impl FnOnce(&mut T, &ConstScalarOrPath, Ty) -> Const + 'a,
1700 ) -> Option<crate::GenericArg> {
1701 let kind = match kind_id {
1702 Either::Left(_) => ParamKind::Type,
1703 Either::Right(id) => {
1704 let ty = db.const_param_ty(id);
1705 ParamKind::Const(ty)
1708 Some(match (arg, kind) {
1709 (GenericArg::Type(type_ref), ParamKind::Type) => {
1710 let ty = for_type(this, type_ref);
1711 GenericArgData::Ty(ty).intern(Interner)
1713 (GenericArg::Const(c), ParamKind::Const(c_ty)) => {
1714 GenericArgData::Const(for_const(this, c, c_ty)).intern(Interner)
1716 (GenericArg::Const(_), ParamKind::Type) => {
1717 GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1719 (GenericArg::Type(t), ParamKind::Const(c_ty)) => {
1720 // We want to recover simple idents, which parser detects them
1721 // as types. Maybe here is not the best place to do it, but
1723 if let TypeRef::Path(p) = t {
1724 let p = p.mod_path();
1725 if p.kind == PathKind::Plain {
1726 if let [n] = p.segments() {
1727 let c = ConstScalarOrPath::Path(n.clone());
1729 GenericArgData::Const(for_const(this, &c, c_ty)).intern(Interner),
1734 unknown_const_as_generic(c_ty)
1736 (GenericArg::Lifetime(_), _) => return None,
1740 pub(crate) fn const_or_path_to_chalk(
1741 db: &dyn HirDatabase,
1742 resolver: &Resolver,
1744 value: &ConstScalarOrPath,
1745 mode: ParamLoweringMode,
1746 args: impl FnOnce() -> Generics,
1747 debruijn: DebruijnIndex,
1750 ConstScalarOrPath::Scalar(s) => intern_const_scalar(s.clone(), expected_ty),
1751 ConstScalarOrPath::Path(n) => {
1752 let path = ModPath::from_segments(PathKind::Plain, Some(n.clone()));
1753 path_to_const(db, resolver, &path, mode, args, debruijn)
1754 .unwrap_or_else(|| unknown_const(expected_ty))
1759 /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
1760 /// num_vars_to_keep) by `TyKind::Unknown`.
1761 fn fallback_bound_vars<T: TypeFoldable<Interner> + HasInterner<Interner = Interner>>(
1763 num_vars_to_keep: usize,
1765 crate::fold_free_vars(
1768 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1769 TyKind::Error.intern(Interner)
1771 bound.shifted_in_from(binders).to_ty(Interner)
1774 |ty, bound, binders| {
1775 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1776 unknown_const(ty.clone())
1778 bound.shifted_in_from(binders).to_const(Interner, ty)