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.
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_scalar_const, 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) => {
243 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
244 let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
245 QuantifiedWhereClauses::from_iter(
247 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
250 let bounds = crate::make_single_type_binders(bounds);
251 TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
253 TypeRef::ImplTrait(bounds) => {
254 match self.impl_trait_mode {
255 ImplTraitLoweringMode::Opaque => {
256 let idx = self.impl_trait_counter.get();
257 self.impl_trait_counter.set(idx + 1);
258 let func = match self.resolver.generic_def() {
259 Some(GenericDefId::FunctionId(f)) => f,
260 _ => panic!("opaque impl trait lowering in non-function"),
263 assert!(idx as usize == self.opaque_type_data.borrow().len());
264 // this dance is to make sure the data is in the right
265 // place even if we encounter more opaque types while
266 // lowering the bounds
267 self.opaque_type_data.borrow_mut().push(ReturnTypeImplTrait {
268 bounds: crate::make_single_type_binders(Vec::new()),
270 // We don't want to lower the bounds inside the binders
271 // we're currently in, because they don't end up inside
272 // those binders. E.g. when we have `impl Trait<impl
273 // OtherTrait<T>>`, the `impl OtherTrait<T>` can't refer
274 // to the self parameter from `impl Trait`, and the
275 // bounds aren't actually stored nested within each
276 // other, but separately. So if the `T` refers to a type
277 // parameter of the outer function, it's just one binder
278 // away instead of two.
279 let actual_opaque_type_data = self
280 .with_debruijn(DebruijnIndex::INNERMOST, |ctx| {
281 ctx.lower_impl_trait(bounds, func)
283 self.opaque_type_data.borrow_mut()[idx as usize] = actual_opaque_type_data;
285 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx);
286 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
287 let generics = generics(self.db.upcast(), func.into());
288 let parameters = generics.bound_vars_subst(self.db, self.in_binders);
289 TyKind::OpaqueType(opaque_ty_id, parameters).intern(Interner)
291 ImplTraitLoweringMode::Param => {
292 let idx = self.impl_trait_counter.get();
293 // FIXME we're probably doing something wrong here
294 self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
295 if let Some(def) = self.resolver.generic_def() {
296 let generics = generics(self.db.upcast(), def);
299 .filter(|(_, data)| {
302 TypeOrConstParamData::TypeParamData(data)
303 if data.provenance == TypeParamProvenance::ArgumentImplTrait
307 .map_or(TyKind::Error, |(id, _)| {
308 TyKind::Placeholder(to_placeholder_idx(self.db, id))
310 param.intern(Interner)
312 TyKind::Error.intern(Interner)
315 ImplTraitLoweringMode::Variable => {
316 let idx = self.impl_trait_counter.get();
317 // FIXME we're probably doing something wrong here
318 self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
325 ) = if let Some(def) = self.resolver.generic_def() {
326 let generics = generics(self.db.upcast(), def);
327 generics.provenance_split()
331 TyKind::BoundVar(BoundVar::new(
333 idx as usize + parent_params + self_params + list_params + const_params,
337 ImplTraitLoweringMode::Disallowed => {
338 // FIXME: report error
339 TyKind::Error.intern(Interner)
343 TypeRef::Macro(macro_call) => {
344 let (expander, recursion_start) = {
345 let mut expander = self.expander.borrow_mut();
346 if expander.is_some() {
347 (Some(expander), false)
349 *expander = Some(Expander::new(
352 self.resolver.module(),
354 (Some(expander), true)
357 let ty = if let Some(mut expander) = expander {
358 let expander_mut = expander.as_mut().unwrap();
359 let macro_call = macro_call.to_node(self.db.upcast());
360 match expander_mut.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
361 Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
363 LowerCtx::new(self.db.upcast(), expander_mut.current_file_id());
364 let type_ref = TypeRef::from_ast(&ctx, expanded);
367 let ty = self.lower_ty(&type_ref);
373 .exit(self.db.upcast(), mark);
382 *self.expander.borrow_mut() = None;
384 ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
386 TypeRef::Error => TyKind::Error.intern(Interner),
391 /// This is only for `generic_predicates_for_param`, where we can't just
392 /// lower the self types of the predicates since that could lead to cycles.
393 /// So we just check here if the `type_ref` resolves to a generic param, and which.
394 fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeOrConstParamId> {
395 let path = match type_ref {
396 TypeRef::Path(path) => path,
399 if path.type_anchor().is_some() {
402 if path.segments().len() > 1 {
406 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
407 Some((it, None)) => it,
411 TypeNs::GenericParam(param_id) => Some(param_id.into()),
416 pub(crate) fn lower_ty_relative_path(
419 // We need the original resolution to lower `Self::AssocTy` correctly
421 remaining_segments: PathSegments<'_>,
422 ) -> (Ty, Option<TypeNs>) {
423 match remaining_segments.len() {
426 // resolve unselected assoc types
427 let segment = remaining_segments.first().unwrap();
428 (self.select_associated_type(res, segment), None)
431 // FIXME report error (ambiguous associated type)
432 (TyKind::Error.intern(Interner), None)
437 pub(crate) fn lower_partly_resolved_path(
440 resolved_segment: PathSegment<'_>,
441 remaining_segments: PathSegments<'_>,
443 ) -> (Ty, Option<TypeNs>) {
444 let ty = match resolution {
445 TypeNs::TraitId(trait_) => {
446 let ty = match remaining_segments.len() {
449 self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None);
450 let segment = remaining_segments.first().unwrap();
453 .trait_data(trait_ref.hir_trait_id())
454 .associated_type_by_name(segment.name);
456 Some(associated_ty) => {
457 // FIXME handle type parameters on the segment
458 TyKind::Alias(AliasTy::Projection(ProjectionTy {
459 associated_ty_id: to_assoc_type_id(associated_ty),
460 substitution: trait_ref.substitution,
465 // FIXME: report error (associated type not found)
466 TyKind::Error.intern(Interner)
472 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
475 let trait_ref = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
476 ctx.lower_trait_ref_from_resolved_path(
483 bounds: crate::make_single_type_binders(
484 QuantifiedWhereClauses::from_iter(
486 Some(crate::wrap_empty_binders(WhereClause::Implemented(
491 lifetime: static_lifetime(),
493 TyKind::Dyn(dyn_ty).intern(Interner)
496 // FIXME report error (ambiguous associated type)
497 TyKind::Error.intern(Interner)
502 TypeNs::GenericParam(param_id) => {
503 let generics = generics(
505 self.resolver.generic_def().expect("generics in scope"),
507 match self.type_param_mode {
508 ParamLoweringMode::Placeholder => {
509 TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into()))
511 ParamLoweringMode::Variable => {
512 let idx = generics.param_idx(param_id.into()).expect("matching generics");
513 TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
518 TypeNs::SelfType(impl_id) => {
519 let generics = generics(self.db.upcast(), impl_id.into());
520 let substs = match self.type_param_mode {
521 ParamLoweringMode::Placeholder => generics.placeholder_subst(self.db),
522 ParamLoweringMode::Variable => {
523 generics.bound_vars_subst(self.db, self.in_binders)
526 self.db.impl_self_ty(impl_id).substitute(Interner, &substs)
528 TypeNs::AdtSelfType(adt) => {
529 let generics = generics(self.db.upcast(), adt.into());
530 let substs = match self.type_param_mode {
531 ParamLoweringMode::Placeholder => generics.placeholder_subst(self.db),
532 ParamLoweringMode::Variable => {
533 generics.bound_vars_subst(self.db, self.in_binders)
536 self.db.ty(adt.into()).substitute(Interner, &substs)
539 TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args),
540 TypeNs::BuiltinType(it) => {
541 self.lower_path_inner(resolved_segment, it.into(), infer_args)
543 TypeNs::TypeAliasId(it) => {
544 self.lower_path_inner(resolved_segment, it.into(), infer_args)
546 // FIXME: report error
547 TypeNs::EnumVariantId(_) => return (TyKind::Error.intern(Interner), None),
549 self.lower_ty_relative_path(ty, Some(resolution), remaining_segments)
552 pub(crate) fn lower_path(&self, path: &Path) -> (Ty, Option<TypeNs>) {
553 // Resolve the path (in type namespace)
554 if let Some(type_ref) = path.type_anchor() {
555 let (ty, res) = self.lower_ty_ext(type_ref);
556 return self.lower_ty_relative_path(ty, res, path.segments());
558 let (resolution, remaining_index) =
559 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
561 None => return (TyKind::Error.intern(Interner), None),
563 let (resolved_segment, remaining_segments) = match remaining_index {
565 path.segments().last().expect("resolved path has at least one element"),
568 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)),
570 self.lower_partly_resolved_path(resolution, resolved_segment, remaining_segments, false)
573 fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
574 let (def, res) = match (self.resolver.generic_def(), res) {
575 (Some(def), Some(res)) => (def, res),
576 _ => return TyKind::Error.intern(Interner),
578 let ty = named_associated_type_shorthand_candidates(
582 Some(segment.name.clone()),
583 move |name, t, associated_ty| {
584 if name == segment.name {
585 let substs = match self.type_param_mode {
586 ParamLoweringMode::Placeholder => {
587 // if we're lowering to placeholders, we have to put
589 let generics = generics(
593 .expect("there should be generics if there's a generic param"),
595 let s = generics.placeholder_subst(self.db);
596 s.apply(t.substitution.clone(), Interner)
598 ParamLoweringMode::Variable => t.substitution.clone(),
600 // We need to shift in the bound vars, since
601 // associated_type_shorthand_candidates does not do that
602 let substs = substs.shifted_in_from(Interner, self.in_binders);
603 // FIXME handle type parameters on the segment
605 TyKind::Alias(AliasTy::Projection(ProjectionTy {
606 associated_ty_id: to_assoc_type_id(associated_ty),
607 substitution: substs,
617 ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
622 segment: PathSegment<'_>,
626 let generic_def = match typeable {
627 TyDefId::BuiltinType(_) => None,
628 TyDefId::AdtId(it) => Some(it.into()),
629 TyDefId::TypeAliasId(it) => Some(it.into()),
631 let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None);
632 self.db.ty(typeable).substitute(Interner, &substs)
635 /// Collect generic arguments from a path into a `Substs`. See also
636 /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
637 pub(super) fn substs_from_path(
640 // Note that we don't call `db.value_type(resolved)` here,
641 // `ValueTyDefId` is just a convenient way to pass generics and
642 // special-case enum variants
643 resolved: ValueTyDefId,
646 let last = path.segments().last().expect("path should have at least one segment");
647 let (segment, generic_def) = match resolved {
648 ValueTyDefId::FunctionId(it) => (last, Some(it.into())),
649 ValueTyDefId::StructId(it) => (last, Some(it.into())),
650 ValueTyDefId::UnionId(it) => (last, Some(it.into())),
651 ValueTyDefId::ConstId(it) => (last, Some(it.into())),
652 ValueTyDefId::StaticId(_) => (last, None),
653 ValueTyDefId::EnumVariantId(var) => {
654 // the generic args for an enum variant may be either specified
655 // on the segment referring to the enum, or on the segment
656 // referring to the variant. So `Option::<T>::None` and
657 // `Option::None::<T>` are both allowed (though the former is
658 // preferred). See also `def_ids_for_path_segments` in rustc.
659 let len = path.segments().len();
660 let penultimate = len.checked_sub(2).and_then(|idx| path.segments().get(idx));
661 let segment = match penultimate {
662 Some(segment) if segment.args_and_bindings.is_some() => segment,
665 (segment, Some(var.parent.into()))
668 self.substs_from_path_segment(segment, generic_def, infer_args, None)
671 fn substs_from_path_segment(
673 segment: PathSegment<'_>,
674 def_generic: Option<GenericDefId>,
676 explicit_self_ty: Option<Ty>,
678 let mut substs = Vec::new();
679 let def_generics = if let Some(def) = def_generic {
680 generics(self.db.upcast(), def)
682 return Substitution::empty(Interner);
684 let (parent_params, self_params, type_params, const_params, impl_trait_params) =
685 def_generics.provenance_split();
687 parent_params + self_params + type_params + const_params + impl_trait_params;
689 let ty_error = GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner);
691 let mut def_generic_iter = def_generics.iter_id();
693 for _ in 0..parent_params {
694 if let Some(eid) = def_generic_iter.next() {
696 Either::Left(_) => substs.push(ty_error.clone()),
697 Either::Right(x) => {
698 substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
704 let fill_self_params = || {
705 for x in explicit_self_ty
707 .map(|x| GenericArgData::Ty(x).intern(Interner))
708 .chain(iter::repeat(ty_error.clone()))
711 if let Some(id) = def_generic_iter.next() {
712 assert!(id.is_left());
717 let mut had_explicit_args = false;
719 if let Some(generic_args) = &segment.args_and_bindings {
720 if !generic_args.has_self_type {
723 let expected_num = if generic_args.has_self_type {
724 self_params + type_params + const_params
726 type_params + const_params
728 let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
729 // if args are provided, it should be all of them, but we can't rely on that
730 for arg in generic_args
733 .filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
737 if let Some(id) = def_generic_iter.next() {
738 if let Some(x) = generic_arg_to_chalk(
743 |_, type_ref| self.lower_ty(type_ref),
745 const_or_path_to_chalk(
750 self.type_param_mode,
756 had_explicit_args = true;
759 // we just filtered them out
760 never!("Unexpected lifetime argument");
768 // handle defaults. In expression or pattern path segments without
769 // explicitly specified type arguments, missing type arguments are inferred
770 // (i.e. defaults aren't used).
771 if !infer_args || had_explicit_args {
772 if let Some(def_generic) = def_generic {
773 let defaults = self.db.generic_defaults(def_generic);
774 assert_eq!(total_len, defaults.len());
776 for default_ty in defaults.iter().skip(substs.len()) {
777 // each default can depend on the previous parameters
778 let substs_so_far = Substitution::from_iter(Interner, substs.clone());
779 if let Some(_id) = def_generic_iter.next() {
780 substs.push(default_ty.clone().substitute(Interner, &substs_so_far));
786 // add placeholders for args that were not provided
787 // FIXME: emit diagnostics in contexts where this is not allowed
788 for eid in def_generic_iter {
790 Either::Left(_) => substs.push(ty_error.clone()),
791 Either::Right(x) => {
792 substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
796 // If this assert fails, it means you pushed into subst but didn't call .next() of def_generic_iter
797 assert_eq!(substs.len(), total_len);
799 Substitution::from_iter(Interner, substs)
802 fn lower_trait_ref_from_path(
805 explicit_self_ty: Option<Ty>,
806 ) -> Option<TraitRef> {
808 match self.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), path.mod_path())? {
809 TypeNs::TraitId(tr) => tr,
812 let segment = path.segments().last().expect("path should have at least one segment");
813 Some(self.lower_trait_ref_from_resolved_path(resolved, segment, explicit_self_ty))
816 pub(crate) fn lower_trait_ref_from_resolved_path(
819 segment: PathSegment<'_>,
820 explicit_self_ty: Option<Ty>,
822 let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
823 TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
828 trait_ref: &HirTraitRef,
829 explicit_self_ty: Option<Ty>,
830 ) -> Option<TraitRef> {
831 self.lower_trait_ref_from_path(&trait_ref.path, explicit_self_ty)
834 fn trait_ref_substs_from_path(
836 segment: PathSegment<'_>,
838 explicit_self_ty: Option<Ty>,
840 self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
843 pub(crate) fn lower_where_predicate(
845 where_predicate: &'a WherePredicate,
846 ignore_bindings: bool,
847 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
848 match where_predicate {
849 WherePredicate::ForLifetime { target, bound, .. }
850 | WherePredicate::TypeBound { target, bound } => {
851 let self_ty = match target {
852 WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
853 WherePredicateTypeTarget::TypeOrConstParam(param_id) => {
854 let generic_def = self.resolver.generic_def().expect("generics in scope");
855 let generics = generics(self.db.upcast(), generic_def);
856 let param_id = hir_def::TypeOrConstParamId {
860 let placeholder = to_placeholder_idx(self.db, param_id);
861 match self.type_param_mode {
862 ParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder),
863 ParamLoweringMode::Variable => {
864 let idx = generics.param_idx(param_id).expect("matching generics");
865 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
871 self.lower_type_bound(bound, self_ty, ignore_bindings)
875 WherePredicate::Lifetime { .. } => vec![].into_iter(),
879 pub(crate) fn lower_type_bound(
881 bound: &'a TypeBound,
883 ignore_bindings: bool,
884 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
885 let mut bindings = None;
886 let trait_ref = match bound {
887 TypeBound::Path(path, TraitBoundModifier::None) => {
888 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
892 // ignore `T: Drop` or `T: Destruct` bounds.
893 // - `T: ~const Drop` has a special meaning in Rust 1.61 that we don't implement.
894 // (So ideally, we'd only ignore `~const Drop` here)
895 // - `Destruct` impls are built-in in 1.62 (current nightlies as of 08-04-2022), so until
896 // the builtin impls are supported by Chalk, we ignore them here.
897 if let Some(lang) = lang_attr(self.db.upcast(), tr.hir_trait_id()) {
898 if lang == "drop" || lang == "destruct" {
904 .map(WhereClause::Implemented)
905 .map(crate::wrap_empty_binders)
907 TypeBound::Path(path, TraitBoundModifier::Maybe) => {
908 let sized_trait = self
910 .lang_item(self.resolver.krate(), SmolStr::new_inline("sized"))
911 .and_then(|lang_item| lang_item.as_trait());
912 // Don't lower associated type bindings as the only possible relaxed trait bound
913 // `?Sized` has no of them.
914 // If we got another trait here ignore the bound completely.
916 .lower_trait_ref_from_path(path, Some(self_ty.clone()))
917 .map(|trait_ref| trait_ref.hir_trait_id());
918 if trait_id == sized_trait {
919 self.unsized_types.borrow_mut().insert(self_ty);
923 TypeBound::ForLifetime(_, path) => {
924 // FIXME Don't silently drop the hrtb lifetimes here
925 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
926 bindings.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
928 TypeBound::Lifetime(_) => None,
929 TypeBound::Error => None,
931 trait_ref.into_iter().chain(
934 .filter(move |_| !ignore_bindings)
935 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)),
939 fn assoc_type_bindings_from_type_bound(
941 bound: &'a TypeBound,
943 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
944 let last_segment = match bound {
945 TypeBound::Path(path, TraitBoundModifier::None) | TypeBound::ForLifetime(_, path) => {
946 path.segments().last()
948 TypeBound::Path(_, TraitBoundModifier::Maybe)
950 | TypeBound::Lifetime(_) => None,
954 .filter_map(|segment| segment.args_and_bindings)
955 .flat_map(|args_and_bindings| &args_and_bindings.bindings)
956 .flat_map(move |binding| {
957 let found = associated_type_by_name_including_super_traits(
962 let (super_trait_ref, associated_ty) = match found {
963 None => return SmallVec::new(),
966 let projection_ty = ProjectionTy {
967 associated_ty_id: to_assoc_type_id(associated_ty),
968 substitution: super_trait_ref.substitution,
970 let mut preds: SmallVec<[_; 1]> = SmallVec::with_capacity(
971 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
973 if let Some(type_ref) = &binding.type_ref {
974 let ty = self.lower_ty(type_ref);
976 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
977 preds.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
979 for bound in &binding.bounds {
980 preds.extend(self.lower_type_bound(
982 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(Interner),
992 bounds: &[Interned<TypeBound>],
994 ) -> ReturnTypeImplTrait {
995 cov_mark::hit!(lower_rpit);
996 let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
997 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
998 let mut predicates: Vec<_> = bounds
1000 .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
1003 if !ctx.unsized_types.borrow().contains(&self_ty) {
1004 let krate = func.lookup(ctx.db.upcast()).module(ctx.db.upcast()).krate();
1005 let sized_trait = ctx
1007 .lang_item(krate, SmolStr::new_inline("sized"))
1008 .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1009 let sized_clause = sized_trait.map(|trait_id| {
1010 let clause = WhereClause::Implemented(TraitRef {
1012 substitution: Substitution::from1(Interner, self_ty.clone()),
1014 crate::wrap_empty_binders(clause)
1016 predicates.extend(sized_clause.into_iter());
1017 predicates.shrink_to_fit();
1021 ReturnTypeImplTrait { bounds: crate::make_single_type_binders(predicates) }
1025 fn count_impl_traits(type_ref: &TypeRef) -> usize {
1027 type_ref.walk(&mut |type_ref| {
1028 if matches!(type_ref, TypeRef::ImplTrait(_)) {
1035 /// Build the signature of a callable item (function, struct or enum variant).
1036 pub fn callable_item_sig(db: &dyn HirDatabase, def: CallableDefId) -> PolyFnSig {
1038 CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f),
1039 CallableDefId::StructId(s) => fn_sig_for_struct_constructor(db, s),
1040 CallableDefId::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e),
1044 pub fn associated_type_shorthand_candidates<R>(
1045 db: &dyn HirDatabase,
1048 cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
1050 named_associated_type_shorthand_candidates(db, def, res, None, cb)
1053 fn named_associated_type_shorthand_candidates<R>(
1054 db: &dyn HirDatabase,
1055 // If the type parameter is defined in an impl and we're in a method, there
1056 // might be additional where clauses to consider
1059 assoc_name: Option<Name>,
1060 mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
1062 let mut search = |t| {
1063 for t in all_super_trait_refs(db, t) {
1064 let data = db.trait_data(t.hir_trait_id());
1066 for (name, assoc_id) in &data.items {
1067 if let AssocItemId::TypeAliasId(alias) = assoc_id {
1068 if let Some(result) = cb(name, &t, *alias) {
1069 return Some(result);
1078 TypeNs::SelfType(impl_id) => search(
1079 // we're _in_ the impl -- the binders get added back later. Correct,
1080 // but it would be nice to make this more explicit
1081 db.impl_trait(impl_id)?.into_value_and_skipped_binders().0,
1083 TypeNs::GenericParam(param_id) => {
1084 let predicates = db.generic_predicates_for_param(def, param_id.into(), assoc_name);
1085 let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
1086 // FIXME: how to correctly handle higher-ranked bounds here?
1087 WhereClause::Implemented(tr) => search(
1089 .shifted_out_to(Interner, DebruijnIndex::ONE)
1090 .expect("FIXME unexpected higher-ranked trait bound"),
1094 if let Some(_) = res {
1097 // Handle `Self::Type` referring to own associated type in trait definitions
1098 if let GenericDefId::TraitId(trait_id) = param_id.parent() {
1099 let generics = generics(db.upcast(), trait_id.into());
1100 if generics.params.type_or_consts[param_id.local_id()].is_trait_self() {
1101 let trait_ref = TyBuilder::trait_ref(db, trait_id)
1102 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
1104 return search(trait_ref);
1113 /// Build the type of all specific fields of a struct or enum variant.
1114 pub(crate) fn field_types_query(
1115 db: &dyn HirDatabase,
1116 variant_id: VariantId,
1117 ) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> {
1118 let var_data = variant_id.variant_data(db.upcast());
1119 let (resolver, def): (_, GenericDefId) = match variant_id {
1120 VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()),
1121 VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()),
1122 VariantId::EnumVariantId(it) => (it.parent.resolver(db.upcast()), it.parent.into()),
1124 let generics = generics(db.upcast(), def);
1125 let mut res = ArenaMap::default();
1127 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1128 for (field_id, field_data) in var_data.fields().iter() {
1129 res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref)))
1134 /// This query exists only to be used when resolving short-hand associated types
1137 /// See the analogous query in rustc and its comment:
1138 /// <https://github.com/rust-lang/rust/blob/9150f844e2624eb013ec78ca08c1d416e6644026/src/librustc_typeck/astconv.rs#L46>
1139 /// This is a query mostly to handle cycles somewhat gracefully; e.g. the
1140 /// following bounds are disallowed: `T: Foo<U::Item>, U: Foo<T::Item>`, but
1141 /// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
1142 pub(crate) fn generic_predicates_for_param_query(
1143 db: &dyn HirDatabase,
1145 param_id: TypeOrConstParamId,
1146 assoc_name: Option<Name>,
1147 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1148 let resolver = def.resolver(db.upcast());
1150 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1151 let generics = generics(db.upcast(), def);
1152 let mut predicates: Vec<_> = resolver
1153 .where_predicates_in_scope()
1154 // we have to filter out all other predicates *first*, before attempting to lower them
1155 .filter(|pred| match pred {
1156 WherePredicate::ForLifetime { target, bound, .. }
1157 | WherePredicate::TypeBound { target, bound, .. } => {
1159 WherePredicateTypeTarget::TypeRef(type_ref) => {
1160 if ctx.lower_ty_only_param(type_ref) != Some(param_id) {
1164 WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
1165 if *local_id != param_id.local_id {
1172 TypeBound::ForLifetime(_, path) | TypeBound::Path(path, _) => {
1173 // Only lower the bound if the trait could possibly define the associated
1174 // type we're looking for.
1176 let assoc_name = match &assoc_name {
1178 None => return true,
1180 let tr = match resolver
1181 .resolve_path_in_type_ns_fully(db.upcast(), path.mod_path())
1183 Some(TypeNs::TraitId(tr)) => tr,
1187 all_super_traits(db.upcast(), tr).iter().any(|tr| {
1188 db.trait_data(*tr).items.iter().any(|(name, item)| {
1189 matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name
1193 TypeBound::Lifetime(_) | TypeBound::Error => false,
1196 WherePredicate::Lifetime { .. } => false,
1199 ctx.lower_where_predicate(pred, true).map(|p| make_binders(db, &generics, p))
1203 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1204 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1205 let implicitly_sized_predicates =
1206 implicitly_sized_clauses(db, param_id.parent, &explicitly_unsized_tys, &subst, &resolver)
1207 .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1208 predicates.extend(implicitly_sized_predicates);
1212 pub(crate) fn generic_predicates_for_param_recover(
1213 _db: &dyn HirDatabase,
1215 _def: &GenericDefId,
1216 _param_id: &TypeOrConstParamId,
1217 _assoc_name: &Option<Name>,
1218 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1222 pub(crate) fn trait_environment_query(
1223 db: &dyn HirDatabase,
1225 ) -> Arc<TraitEnvironment> {
1226 let resolver = def.resolver(db.upcast());
1228 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Placeholder);
1229 let mut traits_in_scope = Vec::new();
1230 let mut clauses = Vec::new();
1231 for pred in resolver.where_predicates_in_scope() {
1232 for pred in ctx.lower_where_predicate(pred, false) {
1233 if let WhereClause::Implemented(tr) = &pred.skip_binders() {
1234 traits_in_scope.push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id()));
1236 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1237 clauses.push(program_clause.into_from_env_clause(Interner));
1241 let container: Option<ItemContainerId> = match def {
1242 // FIXME: is there a function for this?
1243 GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
1244 GenericDefId::AdtId(_) => None,
1245 GenericDefId::TraitId(_) => None,
1246 GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container),
1247 GenericDefId::ImplId(_) => None,
1248 GenericDefId::EnumVariantId(_) => None,
1249 GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container),
1251 if let Some(ItemContainerId::TraitId(trait_id)) = container {
1252 // add `Self: Trait<T1, T2, ...>` to the environment in trait
1253 // function default implementations (and speculative code
1254 // inside consts or type aliases)
1255 cov_mark::hit!(trait_self_implements_self);
1256 let substs = TyBuilder::placeholder_subst(db, trait_id);
1257 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
1258 let pred = WhereClause::Implemented(trait_ref);
1259 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1260 clauses.push(program_clause.into_from_env_clause(Interner));
1263 let subst = generics(db.upcast(), def).placeholder_subst(db);
1264 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1265 let implicitly_sized_clauses =
1266 implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver).map(|pred| {
1267 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1268 program_clause.into_from_env_clause(Interner)
1270 clauses.extend(implicitly_sized_clauses);
1272 let krate = def.module(db.upcast()).krate();
1274 let env = chalk_ir::Environment::new(Interner).add_clauses(Interner, clauses);
1276 Arc::new(TraitEnvironment { krate, traits_from_clauses: traits_in_scope, env })
1279 /// Resolve the where clause(s) of an item with generics.
1280 pub(crate) fn generic_predicates_query(
1281 db: &dyn HirDatabase,
1283 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1284 let resolver = def.resolver(db.upcast());
1286 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1287 let generics = generics(db.upcast(), def);
1289 let mut predicates = resolver
1290 .where_predicates_in_scope()
1292 ctx.lower_where_predicate(pred, false).map(|p| make_binders(db, &generics, p))
1294 .collect::<Vec<_>>();
1296 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1297 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1298 let implicitly_sized_predicates =
1299 implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver)
1300 .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1301 predicates.extend(implicitly_sized_predicates);
1305 /// Generate implicit `: Sized` predicates for all generics that has no `?Sized` bound.
1306 /// Exception is Self of a trait def.
1307 fn implicitly_sized_clauses<'a>(
1308 db: &dyn HirDatabase,
1310 explicitly_unsized_tys: &'a FxHashSet<Ty>,
1311 substitution: &'a Substitution,
1312 resolver: &Resolver,
1313 ) -> impl Iterator<Item = WhereClause> + 'a {
1314 let is_trait_def = matches!(def, GenericDefId::TraitId(..));
1315 let generic_args = &substitution.as_slice(Interner)[is_trait_def as usize..];
1316 let sized_trait = db
1317 .lang_item(resolver.krate(), SmolStr::new_inline("sized"))
1318 .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1320 sized_trait.into_iter().flat_map(move |sized_trait| {
1321 let implicitly_sized_tys = generic_args
1323 .filter_map(|generic_arg| generic_arg.ty(Interner))
1324 .filter(move |&self_ty| !explicitly_unsized_tys.contains(self_ty));
1325 implicitly_sized_tys.map(move |self_ty| {
1326 WhereClause::Implemented(TraitRef {
1327 trait_id: sized_trait,
1328 substitution: Substitution::from1(Interner, self_ty.clone()),
1334 /// Resolve the default type params from generics
1335 pub(crate) fn generic_defaults_query(
1336 db: &dyn HirDatabase,
1338 ) -> Arc<[Binders<chalk_ir::GenericArg<Interner>>]> {
1339 let resolver = def.resolver(db.upcast());
1341 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1342 let generic_params = generics(db.upcast(), def);
1344 let defaults = generic_params
1347 .map(|(idx, (id, p))| {
1349 TypeOrConstParamData::TypeParamData(p) => p,
1350 TypeOrConstParamData::ConstParamData(_) => {
1351 // FIXME: implement const generic defaults
1352 let val = unknown_const_as_generic(
1353 db.const_param_ty(ConstParamId::from_unchecked(id)),
1355 return crate::make_binders_with_count(db, idx, &generic_params, val);
1359 p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
1361 // Each default can only refer to previous parameters.
1362 // type variable default referring to parameter coming
1363 // after it. This is forbidden (FIXME: report
1365 ty = fallback_bound_vars(ty, idx);
1366 let val = GenericArgData::Ty(ty).intern(Interner);
1367 crate::make_binders_with_count(db, idx, &generic_params, val)
1374 pub(crate) fn generic_defaults_recover(
1375 db: &dyn HirDatabase,
1378 ) -> Arc<[Binders<crate::GenericArg>]> {
1379 let generic_params = generics(db.upcast(), *def);
1380 // FIXME: this code is not covered in tests.
1381 // we still need one default per parameter
1382 let defaults = generic_params
1385 .map(|(count, id)| {
1386 let val = match id {
1387 itertools::Either::Left(_) => {
1388 GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1390 itertools::Either::Right(id) => unknown_const_as_generic(db.const_param_ty(id)),
1392 crate::make_binders_with_count(db, count, &generic_params, val)
1399 fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1400 let data = db.function_data(def);
1401 let resolver = def.resolver(db.upcast());
1402 let ctx_params = TyLoweringContext::new(db, &resolver)
1403 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
1404 .with_type_param_mode(ParamLoweringMode::Variable);
1405 let params = data.params.iter().map(|(_, tr)| ctx_params.lower_ty(tr)).collect::<Vec<_>>();
1406 let ctx_ret = TyLoweringContext::new(db, &resolver)
1407 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1408 .with_type_param_mode(ParamLoweringMode::Variable);
1409 let ret = ctx_ret.lower_ty(&data.ret_type);
1410 let generics = generics(db.upcast(), def.into());
1411 let sig = CallableSig::from_params_and_return(params, ret, data.is_varargs());
1412 make_binders(db, &generics, sig)
1415 /// Build the declared type of a function. This should not need to look at the
1417 fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1418 let generics = generics(db.upcast(), def.into());
1419 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1423 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(Interner),
1427 /// Build the declared type of a const.
1428 fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
1429 let data = db.const_data(def);
1430 let generics = generics(db.upcast(), def.into());
1431 let resolver = def.resolver(db.upcast());
1433 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1435 make_binders(db, &generics, ctx.lower_ty(&data.type_ref))
1438 /// Build the declared type of a static.
1439 fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
1440 let data = db.static_data(def);
1441 let resolver = def.resolver(db.upcast());
1442 let ctx = TyLoweringContext::new(db, &resolver);
1444 Binders::empty(Interner, ctx.lower_ty(&data.type_ref))
1447 fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
1448 let struct_data = db.struct_data(def);
1449 let fields = struct_data.variant_data.fields();
1450 let resolver = def.resolver(db.upcast());
1452 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1453 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1454 let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
1455 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1458 /// Build the type of a tuple struct constructor.
1459 fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<Ty> {
1460 let struct_data = db.struct_data(def);
1461 if let StructKind::Unit = struct_data.variant_data.kind() {
1462 return type_for_adt(db, def.into());
1464 let generics = generics(db.upcast(), def.into());
1465 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1469 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
1473 fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
1474 let enum_data = db.enum_data(def.parent);
1475 let var_data = &enum_data.variants[def.local_id];
1476 let fields = var_data.variant_data.fields();
1477 let resolver = def.parent.resolver(db.upcast());
1479 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1480 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1481 let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
1482 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1485 /// Build the type of a tuple enum variant constructor.
1486 fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> Binders<Ty> {
1487 let enum_data = db.enum_data(def.parent);
1488 let var_data = &enum_data.variants[def.local_id].variant_data;
1489 if let StructKind::Unit = var_data.kind() {
1490 return type_for_adt(db, def.parent.into());
1492 let generics = generics(db.upcast(), def.parent.into());
1493 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1497 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(Interner),
1501 fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1502 let generics = generics(db.upcast(), adt.into());
1503 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1504 let ty = TyKind::Adt(crate::AdtId(adt), subst).intern(Interner);
1505 make_binders(db, &generics, ty)
1508 fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1509 let generics = generics(db.upcast(), t.into());
1510 let resolver = t.resolver(db.upcast());
1512 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1513 if db.type_alias_data(t).is_extern {
1514 Binders::empty(Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner))
1516 let type_ref = &db.type_alias_data(t).type_ref;
1517 let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
1518 make_binders(db, &generics, inner)
1522 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1523 pub enum CallableDefId {
1524 FunctionId(FunctionId),
1526 EnumVariantId(EnumVariantId),
1528 impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
1530 impl CallableDefId {
1531 pub fn krate(self, db: &dyn HirDatabase) -> CrateId {
1532 let db = db.upcast();
1534 CallableDefId::FunctionId(f) => f.lookup(db).module(db),
1535 CallableDefId::StructId(s) => s.lookup(db).container,
1536 CallableDefId::EnumVariantId(e) => e.parent.lookup(db).container,
1542 impl From<CallableDefId> for GenericDefId {
1543 fn from(def: CallableDefId) -> GenericDefId {
1545 CallableDefId::FunctionId(f) => f.into(),
1546 CallableDefId::StructId(s) => s.into(),
1547 CallableDefId::EnumVariantId(e) => e.into(),
1552 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1554 BuiltinType(BuiltinType),
1556 TypeAliasId(TypeAliasId),
1558 impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
1560 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1561 pub enum ValueTyDefId {
1562 FunctionId(FunctionId),
1565 EnumVariantId(EnumVariantId),
1569 impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
1571 /// Build the declared type of an item. This depends on the namespace; e.g. for
1572 /// `struct Foo(usize)`, we have two types: The type of the struct itself, and
1573 /// the constructor function `(usize) -> Foo` which lives in the values
1575 pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
1577 TyDefId::BuiltinType(it) => Binders::empty(Interner, TyBuilder::builtin(it)),
1578 TyDefId::AdtId(it) => type_for_adt(db, it),
1579 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
1583 pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> {
1584 let generics = match *def {
1585 TyDefId::BuiltinType(_) => return Binders::empty(Interner, TyKind::Error.intern(Interner)),
1586 TyDefId::AdtId(it) => generics(db.upcast(), it.into()),
1587 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()),
1589 make_binders(db, &generics, TyKind::Error.intern(Interner))
1592 pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
1594 ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
1595 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
1596 ValueTyDefId::UnionId(it) => type_for_adt(db, it.into()),
1597 ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
1598 ValueTyDefId::ConstId(it) => type_for_const(db, it),
1599 ValueTyDefId::StaticId(it) => type_for_static(db, it),
1603 pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> {
1604 let impl_loc = impl_id.lookup(db.upcast());
1605 let impl_data = db.impl_data(impl_id);
1606 let resolver = impl_id.resolver(db.upcast());
1607 let _cx = stdx::panic_context::enter(format!(
1608 "impl_self_ty_query({:?} -> {:?} -> {:?})",
1609 impl_id, impl_loc, impl_data
1611 let generics = generics(db.upcast(), impl_id.into());
1613 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1614 make_binders(db, &generics, ctx.lower_ty(&impl_data.self_ty))
1617 // returns None if def is a type arg
1618 pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
1619 let parent_data = db.generic_params(def.parent());
1620 let data = &parent_data.type_or_consts[def.local_id()];
1621 let resolver = def.parent().resolver(db.upcast());
1622 let ctx = TyLoweringContext::new(db, &resolver);
1624 TypeOrConstParamData::TypeParamData(_) => {
1626 Ty::new(Interner, TyKind::Error)
1628 TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(&d.ty),
1632 pub(crate) fn impl_self_ty_recover(
1633 db: &dyn HirDatabase,
1637 let generics = generics(db.upcast(), (*impl_id).into());
1638 make_binders(db, &generics, TyKind::Error.intern(Interner))
1641 pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
1642 let impl_loc = impl_id.lookup(db.upcast());
1643 let impl_data = db.impl_data(impl_id);
1644 let resolver = impl_id.resolver(db.upcast());
1645 let _cx = stdx::panic_context::enter(format!(
1646 "impl_trait_query({:?} -> {:?} -> {:?})",
1647 impl_id, impl_loc, impl_data
1650 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1651 let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
1652 let target_trait = impl_data.target_trait.as_ref()?;
1653 Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
1656 pub(crate) fn return_type_impl_traits(
1657 db: &dyn HirDatabase,
1658 def: hir_def::FunctionId,
1659 ) -> Option<Arc<Binders<ReturnTypeImplTraits>>> {
1660 // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
1661 let data = db.function_data(def);
1662 let resolver = def.resolver(db.upcast());
1663 let ctx_ret = TyLoweringContext::new(db, &resolver)
1664 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1665 .with_type_param_mode(ParamLoweringMode::Variable);
1666 let _ret = (&ctx_ret).lower_ty(&data.ret_type);
1667 let generics = generics(db.upcast(), def.into());
1668 let return_type_impl_traits =
1669 ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() };
1670 if return_type_impl_traits.impl_traits.is_empty() {
1673 Some(Arc::new(make_binders(db, &generics, return_type_impl_traits)))
1677 pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mutability {
1679 hir_def::type_ref::Mutability::Shared => Mutability::Not,
1680 hir_def::type_ref::Mutability::Mut => Mutability::Mut,
1684 /// Checks if the provided generic arg matches its expected kind, then lower them via
1685 /// provided closures. Use unknown if there was kind mismatch.
1687 /// Returns `Some` of the lowered generic arg. `None` if the provided arg is a lifetime.
1688 pub(crate) fn generic_arg_to_chalk<'a, T>(
1689 db: &dyn HirDatabase,
1690 kind_id: Either<TypeParamId, ConstParamId>,
1691 arg: &'a GenericArg,
1693 for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a,
1694 for_const: impl FnOnce(&mut T, &ConstScalarOrPath, Ty) -> Const + 'a,
1695 ) -> Option<crate::GenericArg> {
1696 let kind = match kind_id {
1697 Either::Left(_) => ParamKind::Type,
1698 Either::Right(id) => {
1699 let ty = db.const_param_ty(id);
1700 ParamKind::Const(ty)
1703 Some(match (arg, kind) {
1704 (GenericArg::Type(type_ref), ParamKind::Type) => {
1705 let ty = for_type(this, type_ref);
1706 GenericArgData::Ty(ty).intern(Interner)
1708 (GenericArg::Const(c), ParamKind::Const(c_ty)) => {
1709 GenericArgData::Const(for_const(this, c, c_ty)).intern(Interner)
1711 (GenericArg::Const(_), ParamKind::Type) => {
1712 GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1714 (GenericArg::Type(t), ParamKind::Const(c_ty)) => {
1715 // We want to recover simple idents, which parser detects them
1716 // as types. Maybe here is not the best place to do it, but
1718 if let TypeRef::Path(p) = t {
1719 let p = p.mod_path();
1720 if p.kind == PathKind::Plain {
1721 if let [n] = p.segments() {
1722 let c = ConstScalarOrPath::Path(n.clone());
1724 GenericArgData::Const(for_const(this, &c, c_ty)).intern(Interner),
1729 unknown_const_as_generic(c_ty)
1731 (GenericArg::Lifetime(_), _) => return None,
1735 pub(crate) fn const_or_path_to_chalk(
1736 db: &dyn HirDatabase,
1737 resolver: &Resolver,
1739 value: &ConstScalarOrPath,
1740 mode: ParamLoweringMode,
1741 args: impl FnOnce() -> Generics,
1742 debruijn: DebruijnIndex,
1745 ConstScalarOrPath::Scalar(s) => intern_scalar_const(s.clone(), expected_ty),
1746 ConstScalarOrPath::Path(n) => {
1747 let path = ModPath::from_segments(PathKind::Plain, Some(n.clone()));
1748 path_to_const(db, resolver, &path, mode, args, debruijn)
1749 .unwrap_or_else(|| unknown_const(expected_ty))
1754 /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
1755 /// num_vars_to_keep) by `TyKind::Unknown`.
1756 fn fallback_bound_vars<T: TypeFoldable<Interner> + HasInterner<Interner = Interner>>(
1758 num_vars_to_keep: usize,
1760 crate::fold_free_vars(
1763 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1764 TyKind::Error.intern(Interner)
1766 bound.shifted_in_from(binders).to_ty(Interner)
1769 |ty, bound, binders| {
1770 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1771 unknown_const(ty.clone())
1773 bound.shifted_in_from(binders).to_const(Interner, ty)