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_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) => {
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(crate) 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 let target_id = TypeOrConstParamId { parent: def, local_id };
1166 if target_id != param_id {
1173 TypeBound::ForLifetime(_, path) | TypeBound::Path(path, _) => {
1174 // Only lower the bound if the trait could possibly define the associated
1175 // type we're looking for.
1177 let assoc_name = match &assoc_name {
1179 None => return true,
1181 let tr = match resolver
1182 .resolve_path_in_type_ns_fully(db.upcast(), path.mod_path())
1184 Some(TypeNs::TraitId(tr)) => tr,
1188 all_super_traits(db.upcast(), tr).iter().any(|tr| {
1189 db.trait_data(*tr).items.iter().any(|(name, item)| {
1190 matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name
1194 TypeBound::Lifetime(_) | TypeBound::Error => false,
1197 WherePredicate::Lifetime { .. } => false,
1200 ctx.lower_where_predicate(pred, true).map(|p| make_binders(db, &generics, p))
1204 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1205 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1206 let implicitly_sized_predicates =
1207 implicitly_sized_clauses(db, param_id.parent, &explicitly_unsized_tys, &subst, &resolver)
1208 .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1209 predicates.extend(implicitly_sized_predicates);
1213 pub(crate) fn generic_predicates_for_param_recover(
1214 _db: &dyn HirDatabase,
1216 _def: &GenericDefId,
1217 _param_id: &TypeOrConstParamId,
1218 _assoc_name: &Option<Name>,
1219 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1223 pub(crate) fn trait_environment_query(
1224 db: &dyn HirDatabase,
1226 ) -> Arc<TraitEnvironment> {
1227 let resolver = def.resolver(db.upcast());
1229 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Placeholder);
1230 let mut traits_in_scope = Vec::new();
1231 let mut clauses = Vec::new();
1232 for pred in resolver.where_predicates_in_scope() {
1233 for pred in ctx.lower_where_predicate(pred, false) {
1234 if let WhereClause::Implemented(tr) = &pred.skip_binders() {
1235 traits_in_scope.push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id()));
1237 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1238 clauses.push(program_clause.into_from_env_clause(Interner));
1242 let container: Option<ItemContainerId> = match def {
1243 // FIXME: is there a function for this?
1244 GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
1245 GenericDefId::AdtId(_) => None,
1246 GenericDefId::TraitId(_) => None,
1247 GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container),
1248 GenericDefId::ImplId(_) => None,
1249 GenericDefId::EnumVariantId(_) => None,
1250 GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container),
1252 if let Some(ItemContainerId::TraitId(trait_id)) = container {
1253 // add `Self: Trait<T1, T2, ...>` to the environment in trait
1254 // function default implementations (and speculative code
1255 // inside consts or type aliases)
1256 cov_mark::hit!(trait_self_implements_self);
1257 let substs = TyBuilder::placeholder_subst(db, trait_id);
1258 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
1259 let pred = WhereClause::Implemented(trait_ref);
1260 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1261 clauses.push(program_clause.into_from_env_clause(Interner));
1264 let subst = generics(db.upcast(), def).placeholder_subst(db);
1265 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1266 let implicitly_sized_clauses =
1267 implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver).map(|pred| {
1268 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1269 program_clause.into_from_env_clause(Interner)
1271 clauses.extend(implicitly_sized_clauses);
1273 let krate = def.module(db.upcast()).krate();
1275 let env = chalk_ir::Environment::new(Interner).add_clauses(Interner, clauses);
1277 Arc::new(TraitEnvironment { krate, traits_from_clauses: traits_in_scope, env })
1280 /// Resolve the where clause(s) of an item with generics.
1281 pub(crate) fn generic_predicates_query(
1282 db: &dyn HirDatabase,
1284 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1285 let resolver = def.resolver(db.upcast());
1287 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1288 let generics = generics(db.upcast(), def);
1290 let mut predicates = resolver
1291 .where_predicates_in_scope()
1293 ctx.lower_where_predicate(pred, false).map(|p| make_binders(db, &generics, p))
1295 .collect::<Vec<_>>();
1297 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1298 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1299 let implicitly_sized_predicates =
1300 implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver)
1301 .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1302 predicates.extend(implicitly_sized_predicates);
1306 /// Generate implicit `: Sized` predicates for all generics that has no `?Sized` bound.
1307 /// Exception is Self of a trait def.
1308 fn implicitly_sized_clauses<'a>(
1309 db: &dyn HirDatabase,
1311 explicitly_unsized_tys: &'a FxHashSet<Ty>,
1312 substitution: &'a Substitution,
1313 resolver: &Resolver,
1314 ) -> impl Iterator<Item = WhereClause> + 'a {
1315 let is_trait_def = matches!(def, GenericDefId::TraitId(..));
1316 let generic_args = &substitution.as_slice(Interner)[is_trait_def as usize..];
1317 let sized_trait = db
1318 .lang_item(resolver.krate(), SmolStr::new_inline("sized"))
1319 .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1321 sized_trait.into_iter().flat_map(move |sized_trait| {
1322 let implicitly_sized_tys = generic_args
1324 .filter_map(|generic_arg| generic_arg.ty(Interner))
1325 .filter(move |&self_ty| !explicitly_unsized_tys.contains(self_ty));
1326 implicitly_sized_tys.map(move |self_ty| {
1327 WhereClause::Implemented(TraitRef {
1328 trait_id: sized_trait,
1329 substitution: Substitution::from1(Interner, self_ty.clone()),
1335 /// Resolve the default type params from generics
1336 pub(crate) fn generic_defaults_query(
1337 db: &dyn HirDatabase,
1339 ) -> Arc<[Binders<chalk_ir::GenericArg<Interner>>]> {
1340 let resolver = def.resolver(db.upcast());
1342 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1343 let generic_params = generics(db.upcast(), def);
1345 let defaults = generic_params
1348 .map(|(idx, (id, p))| {
1350 TypeOrConstParamData::TypeParamData(p) => p,
1351 TypeOrConstParamData::ConstParamData(_) => {
1352 // FIXME: implement const generic defaults
1353 let val = unknown_const_as_generic(
1354 db.const_param_ty(ConstParamId::from_unchecked(id)),
1356 return crate::make_binders_with_count(db, idx, &generic_params, val);
1360 p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
1362 // Each default can only refer to previous parameters.
1363 // type variable default referring to parameter coming
1364 // after it. This is forbidden (FIXME: report
1366 ty = fallback_bound_vars(ty, idx);
1367 let val = GenericArgData::Ty(ty).intern(Interner);
1368 crate::make_binders_with_count(db, idx, &generic_params, val)
1375 pub(crate) fn generic_defaults_recover(
1376 db: &dyn HirDatabase,
1379 ) -> Arc<[Binders<crate::GenericArg>]> {
1380 let generic_params = generics(db.upcast(), *def);
1381 // FIXME: this code is not covered in tests.
1382 // we still need one default per parameter
1383 let defaults = generic_params
1386 .map(|(count, id)| {
1387 let val = match id {
1388 itertools::Either::Left(_) => {
1389 GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1391 itertools::Either::Right(id) => unknown_const_as_generic(db.const_param_ty(id)),
1393 crate::make_binders_with_count(db, count, &generic_params, val)
1400 fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1401 let data = db.function_data(def);
1402 let resolver = def.resolver(db.upcast());
1403 let ctx_params = TyLoweringContext::new(db, &resolver)
1404 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
1405 .with_type_param_mode(ParamLoweringMode::Variable);
1406 let params = data.params.iter().map(|(_, tr)| ctx_params.lower_ty(tr)).collect::<Vec<_>>();
1407 let ctx_ret = TyLoweringContext::new(db, &resolver)
1408 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1409 .with_type_param_mode(ParamLoweringMode::Variable);
1410 let ret = ctx_ret.lower_ty(&data.ret_type);
1411 let generics = generics(db.upcast(), def.into());
1412 let sig = CallableSig::from_params_and_return(params, ret, data.is_varargs());
1413 make_binders(db, &generics, sig)
1416 /// Build the declared type of a function. This should not need to look at the
1418 fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1419 let generics = generics(db.upcast(), def.into());
1420 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1424 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(Interner),
1428 /// Build the declared type of a const.
1429 fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
1430 let data = db.const_data(def);
1431 let generics = generics(db.upcast(), def.into());
1432 let resolver = def.resolver(db.upcast());
1434 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1436 make_binders(db, &generics, ctx.lower_ty(&data.type_ref))
1439 /// Build the declared type of a static.
1440 fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
1441 let data = db.static_data(def);
1442 let resolver = def.resolver(db.upcast());
1443 let ctx = TyLoweringContext::new(db, &resolver);
1445 Binders::empty(Interner, ctx.lower_ty(&data.type_ref))
1448 fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
1449 let struct_data = db.struct_data(def);
1450 let fields = struct_data.variant_data.fields();
1451 let resolver = def.resolver(db.upcast());
1453 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1454 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1455 let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
1456 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1459 /// Build the type of a tuple struct constructor.
1460 fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<Ty> {
1461 let struct_data = db.struct_data(def);
1462 if let StructKind::Unit = struct_data.variant_data.kind() {
1463 return type_for_adt(db, def.into());
1465 let generics = generics(db.upcast(), def.into());
1466 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1470 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
1474 fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
1475 let enum_data = db.enum_data(def.parent);
1476 let var_data = &enum_data.variants[def.local_id];
1477 let fields = var_data.variant_data.fields();
1478 let resolver = def.parent.resolver(db.upcast());
1480 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1481 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1482 let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
1483 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1486 /// Build the type of a tuple enum variant constructor.
1487 fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> Binders<Ty> {
1488 let enum_data = db.enum_data(def.parent);
1489 let var_data = &enum_data.variants[def.local_id].variant_data;
1490 if let StructKind::Unit = var_data.kind() {
1491 return type_for_adt(db, def.parent.into());
1493 let generics = generics(db.upcast(), def.parent.into());
1494 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1498 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(Interner),
1502 fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1503 let generics = generics(db.upcast(), adt.into());
1504 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1505 let ty = TyKind::Adt(crate::AdtId(adt), subst).intern(Interner);
1506 make_binders(db, &generics, ty)
1509 fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1510 let generics = generics(db.upcast(), t.into());
1511 let resolver = t.resolver(db.upcast());
1513 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1514 if db.type_alias_data(t).is_extern {
1515 Binders::empty(Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner))
1517 let type_ref = &db.type_alias_data(t).type_ref;
1518 let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
1519 make_binders(db, &generics, inner)
1523 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1524 pub enum CallableDefId {
1525 FunctionId(FunctionId),
1527 EnumVariantId(EnumVariantId),
1529 impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
1531 impl CallableDefId {
1532 pub fn krate(self, db: &dyn HirDatabase) -> CrateId {
1533 let db = db.upcast();
1535 CallableDefId::FunctionId(f) => f.lookup(db).module(db),
1536 CallableDefId::StructId(s) => s.lookup(db).container,
1537 CallableDefId::EnumVariantId(e) => e.parent.lookup(db).container,
1543 impl From<CallableDefId> for GenericDefId {
1544 fn from(def: CallableDefId) -> GenericDefId {
1546 CallableDefId::FunctionId(f) => f.into(),
1547 CallableDefId::StructId(s) => s.into(),
1548 CallableDefId::EnumVariantId(e) => e.into(),
1553 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1555 BuiltinType(BuiltinType),
1557 TypeAliasId(TypeAliasId),
1559 impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
1561 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1562 pub enum ValueTyDefId {
1563 FunctionId(FunctionId),
1566 EnumVariantId(EnumVariantId),
1570 impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
1572 /// Build the declared type of an item. This depends on the namespace; e.g. for
1573 /// `struct Foo(usize)`, we have two types: The type of the struct itself, and
1574 /// the constructor function `(usize) -> Foo` which lives in the values
1576 pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
1578 TyDefId::BuiltinType(it) => Binders::empty(Interner, TyBuilder::builtin(it)),
1579 TyDefId::AdtId(it) => type_for_adt(db, it),
1580 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
1584 pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> {
1585 let generics = match *def {
1586 TyDefId::BuiltinType(_) => return Binders::empty(Interner, TyKind::Error.intern(Interner)),
1587 TyDefId::AdtId(it) => generics(db.upcast(), it.into()),
1588 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()),
1590 make_binders(db, &generics, TyKind::Error.intern(Interner))
1593 pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
1595 ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
1596 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
1597 ValueTyDefId::UnionId(it) => type_for_adt(db, it.into()),
1598 ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
1599 ValueTyDefId::ConstId(it) => type_for_const(db, it),
1600 ValueTyDefId::StaticId(it) => type_for_static(db, it),
1604 pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> {
1605 let impl_loc = impl_id.lookup(db.upcast());
1606 let impl_data = db.impl_data(impl_id);
1607 let resolver = impl_id.resolver(db.upcast());
1608 let _cx = stdx::panic_context::enter(format!(
1609 "impl_self_ty_query({:?} -> {:?} -> {:?})",
1610 impl_id, impl_loc, impl_data
1612 let generics = generics(db.upcast(), impl_id.into());
1614 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1615 make_binders(db, &generics, ctx.lower_ty(&impl_data.self_ty))
1618 // returns None if def is a type arg
1619 pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
1620 let parent_data = db.generic_params(def.parent());
1621 let data = &parent_data.type_or_consts[def.local_id()];
1622 let resolver = def.parent().resolver(db.upcast());
1623 let ctx = TyLoweringContext::new(db, &resolver);
1625 TypeOrConstParamData::TypeParamData(_) => {
1627 Ty::new(Interner, TyKind::Error)
1629 TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(&d.ty),
1633 pub(crate) fn impl_self_ty_recover(
1634 db: &dyn HirDatabase,
1638 let generics = generics(db.upcast(), (*impl_id).into());
1639 make_binders(db, &generics, TyKind::Error.intern(Interner))
1642 pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
1643 let impl_loc = impl_id.lookup(db.upcast());
1644 let impl_data = db.impl_data(impl_id);
1645 let resolver = impl_id.resolver(db.upcast());
1646 let _cx = stdx::panic_context::enter(format!(
1647 "impl_trait_query({:?} -> {:?} -> {:?})",
1648 impl_id, impl_loc, impl_data
1651 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1652 let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
1653 let target_trait = impl_data.target_trait.as_ref()?;
1654 Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
1657 pub(crate) fn return_type_impl_traits(
1658 db: &dyn HirDatabase,
1659 def: hir_def::FunctionId,
1660 ) -> Option<Arc<Binders<ReturnTypeImplTraits>>> {
1661 // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
1662 let data = db.function_data(def);
1663 let resolver = def.resolver(db.upcast());
1664 let ctx_ret = TyLoweringContext::new(db, &resolver)
1665 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1666 .with_type_param_mode(ParamLoweringMode::Variable);
1667 let _ret = (&ctx_ret).lower_ty(&data.ret_type);
1668 let generics = generics(db.upcast(), def.into());
1669 let return_type_impl_traits =
1670 ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() };
1671 if return_type_impl_traits.impl_traits.is_empty() {
1674 Some(Arc::new(make_binders(db, &generics, return_type_impl_traits)))
1678 pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mutability {
1680 hir_def::type_ref::Mutability::Shared => Mutability::Not,
1681 hir_def::type_ref::Mutability::Mut => Mutability::Mut,
1685 /// Checks if the provided generic arg matches its expected kind, then lower them via
1686 /// provided closures. Use unknown if there was kind mismatch.
1688 /// Returns `Some` of the lowered generic arg. `None` if the provided arg is a lifetime.
1689 pub(crate) fn generic_arg_to_chalk<'a, T>(
1690 db: &dyn HirDatabase,
1691 kind_id: Either<TypeParamId, ConstParamId>,
1692 arg: &'a GenericArg,
1694 for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a,
1695 for_const: impl FnOnce(&mut T, &ConstScalarOrPath, Ty) -> Const + 'a,
1696 ) -> Option<crate::GenericArg> {
1697 let kind = match kind_id {
1698 Either::Left(_) => ParamKind::Type,
1699 Either::Right(id) => {
1700 let ty = db.const_param_ty(id);
1701 ParamKind::Const(ty)
1704 Some(match (arg, kind) {
1705 (GenericArg::Type(type_ref), ParamKind::Type) => {
1706 let ty = for_type(this, type_ref);
1707 GenericArgData::Ty(ty).intern(Interner)
1709 (GenericArg::Const(c), ParamKind::Const(c_ty)) => {
1710 GenericArgData::Const(for_const(this, c, c_ty)).intern(Interner)
1712 (GenericArg::Const(_), ParamKind::Type) => {
1713 GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1715 (GenericArg::Type(t), ParamKind::Const(c_ty)) => {
1716 // We want to recover simple idents, which parser detects them
1717 // as types. Maybe here is not the best place to do it, but
1719 if let TypeRef::Path(p) = t {
1720 let p = p.mod_path();
1721 if p.kind == PathKind::Plain {
1722 if let [n] = p.segments() {
1723 let c = ConstScalarOrPath::Path(n.clone());
1725 GenericArgData::Const(for_const(this, &c, c_ty)).intern(Interner),
1730 unknown_const_as_generic(c_ty)
1732 (GenericArg::Lifetime(_), _) => return None,
1736 pub(crate) fn const_or_path_to_chalk(
1737 db: &dyn HirDatabase,
1738 resolver: &Resolver,
1740 value: &ConstScalarOrPath,
1741 mode: ParamLoweringMode,
1742 args: impl FnOnce() -> Generics,
1743 debruijn: DebruijnIndex,
1746 ConstScalarOrPath::Scalar(s) => intern_const_scalar(s.clone(), expected_ty),
1747 ConstScalarOrPath::Path(n) => {
1748 let path = ModPath::from_segments(PathKind::Plain, Some(n.clone()));
1749 path_to_const(db, resolver, &path, mode, args, debruijn)
1750 .unwrap_or_else(|| unknown_const(expected_ty))
1755 /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
1756 /// num_vars_to_keep) by `TyKind::Unknown`.
1757 fn fallback_bound_vars<T: TypeFoldable<Interner> + HasInterner<Interner = Interner>>(
1759 num_vars_to_keep: usize,
1761 crate::fold_free_vars(
1764 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1765 TyKind::Error.intern(Interner)
1767 bound.shifted_in_from(binders).to_ty(Interner)
1770 |ty, bound, binders| {
1771 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1772 unknown_const(ty.clone())
1774 bound.shifted_in_from(binders).to_const(Interner, ty)