1 //! Methods for lowering the HIR to types. There are two main cases here:
3 //! - Lowering a type reference like `&usize` or `Option<foo::bar::Baz>` to a
4 //! type: The entry point for this is `Ty::from_hir`.
5 //! - Building the type for an item: This happens through the `type_for_def` query.
7 //! This usually involves resolving names, collecting generic arguments etc.
9 cell::{Cell, RefCell, RefMut},
16 cast::Cast, fold::Shift, fold::TypeFoldable, interner::HasInterner, Mutability, Safety,
21 body::{Expander, LowerCtx},
22 builtin_type::BuiltinType,
24 TypeOrConstParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
28 path::{GenericArg, ModPath, Path, PathKind, PathSegment, PathSegments},
29 resolver::{HasResolver, Resolver, TypeNs},
31 ConstScalarOrPath, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef,
33 AdtId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId,
34 HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
35 TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, VariantId,
37 use hir_expand::{name::Name, ExpandResult};
38 use itertools::Either;
39 use la_arena::ArenaMap;
40 use rustc_hash::FxHashSet;
41 use smallvec::SmallVec;
42 use stdx::{impl_from, never};
43 use syntax::{ast, SmolStr};
47 consteval::{intern_const_scalar, path_to_const, unknown_const, unknown_const_as_generic},
51 static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
53 utils::{all_super_trait_refs, associated_type_by_name_including_super_traits, generics},
54 AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, DebruijnIndex, DynTy, FnPointer,
55 FnSig, FnSubst, GenericArgData, ImplTraitId, Interner, ParamKind, PolyFnSig, ProjectionTy,
56 QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits,
57 Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
61 pub struct TyLoweringContext<'a> {
62 pub db: &'a dyn HirDatabase,
63 pub resolver: &'a Resolver,
64 in_binders: DebruijnIndex,
65 /// Note: Conceptually, it's thinkable that we could be in a location where
66 /// some type params should be represented as placeholders, and others
67 /// should be converted to variables. I think in practice, this isn't
68 /// possible currently, so this should be fine for now.
69 pub type_param_mode: ParamLoweringMode,
70 pub impl_trait_mode: ImplTraitLoweringMode,
71 impl_trait_counter: Cell<u16>,
72 /// When turning `impl Trait` into opaque types, we have to collect the
73 /// bounds at the same time to get the IDs correct (without becoming too
74 /// complicated). I don't like using interior mutability (as for the
75 /// counter), but I've tried and failed to make the lifetimes work for
76 /// passing around a `&mut TyLoweringContext`. The core problem is that
77 /// we're grouping the mutable data (the counter and this field) together
78 /// with the immutable context (the references to the DB and resolver).
79 /// Splitting this up would be a possible fix.
80 opaque_type_data: RefCell<Vec<ReturnTypeImplTrait>>,
81 expander: RefCell<Option<Expander>>,
82 /// Tracks types with explicit `?Sized` bounds.
83 pub(crate) unsized_types: RefCell<FxHashSet<Ty>>,
86 impl<'a> TyLoweringContext<'a> {
87 pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver) -> Self {
88 let impl_trait_counter = Cell::new(0);
89 let impl_trait_mode = ImplTraitLoweringMode::Disallowed;
90 let type_param_mode = ParamLoweringMode::Placeholder;
91 let in_binders = DebruijnIndex::INNERMOST;
92 let opaque_type_data = RefCell::new(Vec::new());
101 expander: RefCell::new(None),
102 unsized_types: RefCell::default(),
106 pub fn with_debruijn<T>(
108 debruijn: DebruijnIndex,
109 f: impl FnOnce(&TyLoweringContext<'_>) -> T,
111 let opaque_ty_data_vec = self.opaque_type_data.take();
112 let expander = self.expander.take();
113 let unsized_types = self.unsized_types.take();
115 in_binders: debruijn,
116 impl_trait_counter: Cell::new(self.impl_trait_counter.get()),
117 opaque_type_data: RefCell::new(opaque_ty_data_vec),
118 expander: RefCell::new(expander),
119 unsized_types: RefCell::new(unsized_types),
122 let result = f(&new_ctx);
123 self.impl_trait_counter.set(new_ctx.impl_trait_counter.get());
124 self.opaque_type_data.replace(new_ctx.opaque_type_data.into_inner());
125 self.expander.replace(new_ctx.expander.into_inner());
126 self.unsized_types.replace(new_ctx.unsized_types.into_inner());
130 pub fn with_shifted_in<T>(
132 debruijn: DebruijnIndex,
133 f: impl FnOnce(&TyLoweringContext<'_>) -> T,
135 self.with_debruijn(self.in_binders.shifted_in_from(debruijn), f)
138 pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
139 Self { impl_trait_mode, ..self }
142 pub fn with_type_param_mode(self, type_param_mode: ParamLoweringMode) -> Self {
143 Self { type_param_mode, ..self }
147 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
148 pub enum ImplTraitLoweringMode {
149 /// `impl Trait` gets lowered into an opaque type that doesn't unify with
150 /// anything except itself. This is used in places where values flow 'out',
151 /// i.e. for arguments of the function we're currently checking, and return
152 /// types of functions we're calling.
154 /// `impl Trait` gets lowered into a type variable. Used for argument
155 /// position impl Trait when inside the respective function, since it allows
156 /// us to support that without Chalk.
158 /// `impl Trait` gets lowered into a variable that can unify with some
159 /// type. This is used in places where values flow 'in', i.e. for arguments
160 /// of functions we're calling, and the return type of the function we're
161 /// currently checking.
163 /// `impl Trait` is disallowed and will be an error.
167 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
168 pub enum ParamLoweringMode {
173 impl<'a> TyLoweringContext<'a> {
174 pub fn lower_ty(&self, type_ref: &TypeRef) -> Ty {
175 self.lower_ty_ext(type_ref).0
178 fn generics(&self) -> Generics {
183 .expect("there should be generics if there's a generic param"),
187 pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
189 let ty = match type_ref {
190 TypeRef::Never => TyKind::Never.intern(Interner),
191 TypeRef::Tuple(inner) => {
192 let inner_tys = inner.iter().map(|tr| self.lower_ty(tr));
193 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(Interner, inner_tys))
196 TypeRef::Path(path) => {
197 let (ty, res_) = self.lower_path(path);
201 TypeRef::RawPtr(inner, mutability) => {
202 let inner_ty = self.lower_ty(inner);
203 TyKind::Raw(lower_to_chalk_mutability(*mutability), inner_ty).intern(Interner)
205 TypeRef::Array(inner, len) => {
206 let inner_ty = self.lower_ty(inner);
207 let const_len = const_or_path_to_chalk(
212 self.type_param_mode,
217 TyKind::Array(inner_ty, const_len).intern(Interner)
219 TypeRef::Slice(inner) => {
220 let inner_ty = self.lower_ty(inner);
221 TyKind::Slice(inner_ty).intern(Interner)
223 TypeRef::Reference(inner, _, mutability) => {
224 let inner_ty = self.lower_ty(inner);
225 let lifetime = static_lifetime();
226 TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty)
229 TypeRef::Placeholder => TyKind::Error.intern(Interner),
230 TypeRef::Fn(params, is_varargs) => {
231 let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
232 Substitution::from_iter(Interner, params.iter().map(|(_, tr)| ctx.lower_ty(tr)))
234 TyKind::Function(FnPointer {
235 num_binders: 0, // FIXME lower `for<'a> fn()` correctly
236 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
237 substitution: FnSubst(substs),
241 TypeRef::DynTrait(bounds) => self.lower_dyn_trait(bounds),
242 TypeRef::ImplTrait(bounds) => {
243 match self.impl_trait_mode {
244 ImplTraitLoweringMode::Opaque => {
245 let idx = self.impl_trait_counter.get();
246 self.impl_trait_counter.set(idx + 1);
247 let func = match self.resolver.generic_def() {
248 Some(GenericDefId::FunctionId(f)) => f,
249 _ => panic!("opaque impl trait lowering in non-function"),
252 assert!(idx as usize == self.opaque_type_data.borrow().len());
253 // this dance is to make sure the data is in the right
254 // place even if we encounter more opaque types while
255 // lowering the bounds
256 self.opaque_type_data.borrow_mut().push(ReturnTypeImplTrait {
257 bounds: crate::make_single_type_binders(Vec::new()),
259 // We don't want to lower the bounds inside the binders
260 // we're currently in, because they don't end up inside
261 // those binders. E.g. when we have `impl Trait<impl
262 // OtherTrait<T>>`, the `impl OtherTrait<T>` can't refer
263 // to the self parameter from `impl Trait`, and the
264 // bounds aren't actually stored nested within each
265 // other, but separately. So if the `T` refers to a type
266 // parameter of the outer function, it's just one binder
267 // away instead of two.
268 let actual_opaque_type_data = self
269 .with_debruijn(DebruijnIndex::INNERMOST, |ctx| {
270 ctx.lower_impl_trait(bounds, func)
272 self.opaque_type_data.borrow_mut()[idx as usize] = actual_opaque_type_data;
274 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx);
275 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
276 let generics = generics(self.db.upcast(), func.into());
277 let parameters = generics.bound_vars_subst(self.db, self.in_binders);
278 TyKind::OpaqueType(opaque_ty_id, parameters).intern(Interner)
280 ImplTraitLoweringMode::Param => {
281 let idx = self.impl_trait_counter.get();
282 // FIXME we're probably doing something wrong here
283 self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
284 if let Some(def) = self.resolver.generic_def() {
285 let generics = generics(self.db.upcast(), def);
288 .filter(|(_, data)| {
291 TypeOrConstParamData::TypeParamData(data)
292 if data.provenance == TypeParamProvenance::ArgumentImplTrait
296 .map_or(TyKind::Error, |(id, _)| {
297 TyKind::Placeholder(to_placeholder_idx(self.db, id))
299 param.intern(Interner)
301 TyKind::Error.intern(Interner)
304 ImplTraitLoweringMode::Variable => {
305 let idx = self.impl_trait_counter.get();
306 // FIXME we're probably doing something wrong here
307 self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
314 ) = if let Some(def) = self.resolver.generic_def() {
315 let generics = generics(self.db.upcast(), def);
316 generics.provenance_split()
320 TyKind::BoundVar(BoundVar::new(
322 idx as usize + parent_params + self_params + list_params + const_params,
326 ImplTraitLoweringMode::Disallowed => {
327 // FIXME: report error
328 TyKind::Error.intern(Interner)
332 TypeRef::Macro(macro_call) => {
333 let (mut expander, recursion_start) = {
334 match RefMut::filter_map(self.expander.borrow_mut(), Option::as_mut) {
335 Ok(expander) => (expander, false),
337 RefMut::map(expander, |it| {
338 it.insert(Expander::new(
341 self.resolver.module(),
349 let macro_call = macro_call.to_node(self.db.upcast());
350 match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
351 Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
352 let ctx = LowerCtx::new(self.db.upcast(), expander.current_file_id());
353 let type_ref = TypeRef::from_ast(&ctx, expanded);
356 let ty = self.lower_ty(&type_ref);
362 .exit(self.db.upcast(), mark);
369 *self.expander.borrow_mut() = None;
371 ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
373 TypeRef::Error => TyKind::Error.intern(Interner),
378 /// This is only for `generic_predicates_for_param`, where we can't just
379 /// lower the self types of the predicates since that could lead to cycles.
380 /// So we just check here if the `type_ref` resolves to a generic param, and which.
381 fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeOrConstParamId> {
382 let path = match type_ref {
383 TypeRef::Path(path) => path,
386 if path.type_anchor().is_some() {
389 if path.segments().len() > 1 {
393 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
394 Some((it, None)) => it,
398 TypeNs::GenericParam(param_id) => Some(param_id.into()),
403 pub(crate) fn lower_ty_relative_path(
406 // We need the original resolution to lower `Self::AssocTy` correctly
408 remaining_segments: PathSegments<'_>,
409 ) -> (Ty, Option<TypeNs>) {
410 match remaining_segments.len() {
413 // resolve unselected assoc types
414 let segment = remaining_segments.first().unwrap();
415 (self.select_associated_type(res, segment), None)
418 // FIXME report error (ambiguous associated type)
419 (TyKind::Error.intern(Interner), None)
424 pub(crate) fn lower_partly_resolved_path(
427 resolved_segment: PathSegment<'_>,
428 remaining_segments: PathSegments<'_>,
430 ) -> (Ty, Option<TypeNs>) {
431 let ty = match resolution {
432 TypeNs::TraitId(trait_) => {
433 let ty = match remaining_segments.len() {
436 self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None);
437 let segment = remaining_segments.first().unwrap();
440 .trait_data(trait_ref.hir_trait_id())
441 .associated_type_by_name(segment.name);
443 Some(associated_ty) => {
444 // FIXME handle type parameters on the segment
445 TyKind::Alias(AliasTy::Projection(ProjectionTy {
446 associated_ty_id: to_assoc_type_id(associated_ty),
447 substitution: trait_ref.substitution,
452 // FIXME: report error (associated type not found)
453 TyKind::Error.intern(Interner)
458 // Trait object type without dyn; this should be handled in upstream. See
460 stdx::never!("unexpected fully resolved trait path");
461 TyKind::Error.intern(Interner)
464 // FIXME report error (ambiguous associated type)
465 TyKind::Error.intern(Interner)
470 TypeNs::GenericParam(param_id) => {
471 let generics = generics(
473 self.resolver.generic_def().expect("generics in scope"),
475 match self.type_param_mode {
476 ParamLoweringMode::Placeholder => {
477 TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into()))
479 ParamLoweringMode::Variable => {
480 let idx = match generics.param_idx(param_id.into()) {
482 never!("no matching generics");
483 return (TyKind::Error.intern(Interner), None);
488 TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
493 TypeNs::SelfType(impl_id) => {
494 let generics = generics(self.db.upcast(), impl_id.into());
495 let substs = match self.type_param_mode {
496 ParamLoweringMode::Placeholder => generics.placeholder_subst(self.db),
497 ParamLoweringMode::Variable => {
498 generics.bound_vars_subst(self.db, self.in_binders)
501 self.db.impl_self_ty(impl_id).substitute(Interner, &substs)
503 TypeNs::AdtSelfType(adt) => {
504 let generics = generics(self.db.upcast(), adt.into());
505 let substs = match self.type_param_mode {
506 ParamLoweringMode::Placeholder => generics.placeholder_subst(self.db),
507 ParamLoweringMode::Variable => {
508 generics.bound_vars_subst(self.db, self.in_binders)
511 self.db.ty(adt.into()).substitute(Interner, &substs)
514 TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args),
515 TypeNs::BuiltinType(it) => {
516 self.lower_path_inner(resolved_segment, it.into(), infer_args)
518 TypeNs::TypeAliasId(it) => {
519 self.lower_path_inner(resolved_segment, it.into(), infer_args)
521 // FIXME: report error
522 TypeNs::EnumVariantId(_) => return (TyKind::Error.intern(Interner), None),
524 self.lower_ty_relative_path(ty, Some(resolution), remaining_segments)
527 pub(crate) fn lower_path(&self, path: &Path) -> (Ty, Option<TypeNs>) {
528 // Resolve the path (in type namespace)
529 if let Some(type_ref) = path.type_anchor() {
530 let (ty, res) = self.lower_ty_ext(type_ref);
531 return self.lower_ty_relative_path(ty, res, path.segments());
534 let (resolution, remaining_index) =
535 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
537 None => return (TyKind::Error.intern(Interner), None),
540 if matches!(resolution, TypeNs::TraitId(_)) && remaining_index.is_none() {
541 // trait object type without dyn
542 let bound = TypeBound::Path(path.clone(), TraitBoundModifier::None);
543 let ty = self.lower_dyn_trait(&[Interned::new(bound)]);
547 let (resolved_segment, remaining_segments) = match remaining_index {
549 path.segments().last().expect("resolved path has at least one element"),
552 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)),
554 self.lower_partly_resolved_path(resolution, resolved_segment, remaining_segments, false)
557 fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
558 let (def, res) = match (self.resolver.generic_def(), res) {
559 (Some(def), Some(res)) => (def, res),
560 _ => return TyKind::Error.intern(Interner),
562 let ty = named_associated_type_shorthand_candidates(
566 Some(segment.name.clone()),
567 move |name, t, associated_ty| {
568 if name == segment.name {
569 let substs = match self.type_param_mode {
570 ParamLoweringMode::Placeholder => {
571 // if we're lowering to placeholders, we have to put
573 let generics = generics(
577 .expect("there should be generics if there's a generic param"),
579 let s = generics.placeholder_subst(self.db);
580 s.apply(t.substitution.clone(), Interner)
582 ParamLoweringMode::Variable => t.substitution.clone(),
584 // We need to shift in the bound vars, since
585 // associated_type_shorthand_candidates does not do that
586 let substs = substs.shifted_in_from(Interner, self.in_binders);
587 // FIXME handle type parameters on the segment
589 TyKind::Alias(AliasTy::Projection(ProjectionTy {
590 associated_ty_id: to_assoc_type_id(associated_ty),
591 substitution: substs,
601 ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
606 segment: PathSegment<'_>,
610 let generic_def = match typeable {
611 TyDefId::BuiltinType(_) => None,
612 TyDefId::AdtId(it) => Some(it.into()),
613 TyDefId::TypeAliasId(it) => Some(it.into()),
615 let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None);
616 self.db.ty(typeable).substitute(Interner, &substs)
619 /// Collect generic arguments from a path into a `Substs`. See also
620 /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
621 pub(super) fn substs_from_path(
624 // Note that we don't call `db.value_type(resolved)` here,
625 // `ValueTyDefId` is just a convenient way to pass generics and
626 // special-case enum variants
627 resolved: ValueTyDefId,
630 let last = path.segments().last().expect("path should have at least one segment");
631 let (segment, generic_def) = match resolved {
632 ValueTyDefId::FunctionId(it) => (last, Some(it.into())),
633 ValueTyDefId::StructId(it) => (last, Some(it.into())),
634 ValueTyDefId::UnionId(it) => (last, Some(it.into())),
635 ValueTyDefId::ConstId(it) => (last, Some(it.into())),
636 ValueTyDefId::StaticId(_) => (last, None),
637 ValueTyDefId::EnumVariantId(var) => {
638 // the generic args for an enum variant may be either specified
639 // on the segment referring to the enum, or on the segment
640 // referring to the variant. So `Option::<T>::None` and
641 // `Option::None::<T>` are both allowed (though the former is
642 // preferred). See also `def_ids_for_path_segments` in rustc.
643 let len = path.segments().len();
644 let penultimate = len.checked_sub(2).and_then(|idx| path.segments().get(idx));
645 let segment = match penultimate {
646 Some(segment) if segment.args_and_bindings.is_some() => segment,
649 (segment, Some(var.parent.into()))
652 self.substs_from_path_segment(segment, generic_def, infer_args, None)
655 fn substs_from_path_segment(
657 segment: PathSegment<'_>,
658 def_generic: Option<GenericDefId>,
660 explicit_self_ty: Option<Ty>,
662 let mut substs = Vec::new();
663 let def_generics = if let Some(def) = def_generic {
664 generics(self.db.upcast(), def)
666 return Substitution::empty(Interner);
668 let (parent_params, self_params, type_params, const_params, impl_trait_params) =
669 def_generics.provenance_split();
671 parent_params + self_params + type_params + const_params + impl_trait_params;
673 let ty_error = GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner);
675 let mut def_generic_iter = def_generics.iter_id();
677 for _ in 0..parent_params {
678 if let Some(eid) = def_generic_iter.next() {
680 Either::Left(_) => substs.push(ty_error.clone()),
681 Either::Right(x) => {
682 substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
688 let fill_self_params = || {
689 for x in explicit_self_ty
691 .map(|x| GenericArgData::Ty(x).intern(Interner))
692 .chain(iter::repeat(ty_error.clone()))
695 if let Some(id) = def_generic_iter.next() {
696 assert!(id.is_left());
701 let mut had_explicit_args = false;
703 if let Some(generic_args) = &segment.args_and_bindings {
704 if !generic_args.has_self_type {
707 let expected_num = if generic_args.has_self_type {
708 self_params + type_params + const_params
710 type_params + const_params
712 let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
713 // if args are provided, it should be all of them, but we can't rely on that
714 for arg in generic_args
717 .filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
721 if let Some(id) = def_generic_iter.next() {
722 if let Some(x) = generic_arg_to_chalk(
727 |_, type_ref| self.lower_ty(type_ref),
729 const_or_path_to_chalk(
734 self.type_param_mode,
740 had_explicit_args = true;
743 // we just filtered them out
744 never!("Unexpected lifetime argument");
752 // handle defaults. In expression or pattern path segments without
753 // explicitly specified type arguments, missing type arguments are inferred
754 // (i.e. defaults aren't used).
755 if !infer_args || had_explicit_args {
756 if let Some(def_generic) = def_generic {
757 let defaults = self.db.generic_defaults(def_generic);
758 assert_eq!(total_len, defaults.len());
760 for default_ty in defaults.iter().skip(substs.len()) {
761 // each default can depend on the previous parameters
762 let substs_so_far = Substitution::from_iter(Interner, substs.clone());
763 if let Some(_id) = def_generic_iter.next() {
764 substs.push(default_ty.clone().substitute(Interner, &substs_so_far));
770 // add placeholders for args that were not provided
771 // FIXME: emit diagnostics in contexts where this is not allowed
772 for eid in def_generic_iter {
774 Either::Left(_) => substs.push(ty_error.clone()),
775 Either::Right(x) => {
776 substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
780 // If this assert fails, it means you pushed into subst but didn't call .next() of def_generic_iter
781 assert_eq!(substs.len(), total_len);
783 Substitution::from_iter(Interner, substs)
786 fn lower_trait_ref_from_path(
789 explicit_self_ty: Option<Ty>,
790 ) -> Option<TraitRef> {
792 match self.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), path.mod_path())? {
793 TypeNs::TraitId(tr) => tr,
796 let segment = path.segments().last().expect("path should have at least one segment");
797 Some(self.lower_trait_ref_from_resolved_path(resolved, segment, explicit_self_ty))
800 pub(crate) fn lower_trait_ref_from_resolved_path(
803 segment: PathSegment<'_>,
804 explicit_self_ty: Option<Ty>,
806 let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
807 TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
812 trait_ref: &HirTraitRef,
813 explicit_self_ty: Option<Ty>,
814 ) -> Option<TraitRef> {
815 self.lower_trait_ref_from_path(&trait_ref.path, explicit_self_ty)
818 fn trait_ref_substs_from_path(
820 segment: PathSegment<'_>,
822 explicit_self_ty: Option<Ty>,
824 self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
827 pub(crate) fn lower_where_predicate(
829 where_predicate: &'a WherePredicate,
830 ignore_bindings: bool,
831 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
832 match where_predicate {
833 WherePredicate::ForLifetime { target, bound, .. }
834 | WherePredicate::TypeBound { target, bound } => {
835 let self_ty = match target {
836 WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
837 WherePredicateTypeTarget::TypeOrConstParam(param_id) => {
838 let generic_def = self.resolver.generic_def().expect("generics in scope");
839 let generics = generics(self.db.upcast(), generic_def);
840 let param_id = hir_def::TypeOrConstParamId {
844 let placeholder = to_placeholder_idx(self.db, param_id);
845 match self.type_param_mode {
846 ParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder),
847 ParamLoweringMode::Variable => {
848 let idx = generics.param_idx(param_id).expect("matching generics");
849 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
855 self.lower_type_bound(bound, self_ty, ignore_bindings)
859 WherePredicate::Lifetime { .. } => vec![].into_iter(),
863 pub(crate) fn lower_type_bound(
865 bound: &'a TypeBound,
867 ignore_bindings: bool,
868 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
869 let mut bindings = None;
870 let trait_ref = match bound {
871 TypeBound::Path(path, TraitBoundModifier::None) => {
872 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
876 // ignore `T: Drop` or `T: Destruct` bounds.
877 // - `T: ~const Drop` has a special meaning in Rust 1.61 that we don't implement.
878 // (So ideally, we'd only ignore `~const Drop` here)
879 // - `Destruct` impls are built-in in 1.62 (current nightlies as of 08-04-2022), so until
880 // the builtin impls are supported by Chalk, we ignore them here.
881 if let Some(lang) = lang_attr(self.db.upcast(), tr.hir_trait_id()) {
882 if lang == "drop" || lang == "destruct" {
888 .map(WhereClause::Implemented)
889 .map(crate::wrap_empty_binders)
891 TypeBound::Path(path, TraitBoundModifier::Maybe) => {
892 let sized_trait = self
894 .lang_item(self.resolver.krate(), SmolStr::new_inline("sized"))
895 .and_then(|lang_item| lang_item.as_trait());
896 // Don't lower associated type bindings as the only possible relaxed trait bound
897 // `?Sized` has no of them.
898 // If we got another trait here ignore the bound completely.
900 .lower_trait_ref_from_path(path, Some(self_ty.clone()))
901 .map(|trait_ref| trait_ref.hir_trait_id());
902 if trait_id == sized_trait {
903 self.unsized_types.borrow_mut().insert(self_ty);
907 TypeBound::ForLifetime(_, path) => {
908 // FIXME Don't silently drop the hrtb lifetimes here
909 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
910 bindings.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
912 TypeBound::Lifetime(_) => None,
913 TypeBound::Error => None,
915 trait_ref.into_iter().chain(
918 .filter(move |_| !ignore_bindings)
919 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)),
923 fn assoc_type_bindings_from_type_bound(
925 bound: &'a TypeBound,
927 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
928 let last_segment = match bound {
929 TypeBound::Path(path, TraitBoundModifier::None) | TypeBound::ForLifetime(_, path) => {
930 path.segments().last()
932 TypeBound::Path(_, TraitBoundModifier::Maybe)
934 | TypeBound::Lifetime(_) => None,
938 .filter_map(|segment| segment.args_and_bindings)
939 .flat_map(|args_and_bindings| &args_and_bindings.bindings)
940 .flat_map(move |binding| {
941 let found = associated_type_by_name_including_super_traits(
946 let (super_trait_ref, associated_ty) = match found {
947 None => return SmallVec::new(),
950 let projection_ty = ProjectionTy {
951 associated_ty_id: to_assoc_type_id(associated_ty),
952 substitution: super_trait_ref.substitution,
954 let mut preds: SmallVec<[_; 1]> = SmallVec::with_capacity(
955 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
957 if let Some(type_ref) = &binding.type_ref {
958 let ty = self.lower_ty(type_ref);
960 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
961 preds.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
963 for bound in &binding.bounds {
964 preds.extend(self.lower_type_bound(
966 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(Interner),
974 fn lower_dyn_trait(&self, bounds: &[Interned<TypeBound>]) -> Ty {
975 let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
976 let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
977 QuantifiedWhereClauses::from_iter(
979 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
982 let bounds = crate::make_single_type_binders(bounds);
983 TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
988 bounds: &[Interned<TypeBound>],
990 ) -> ReturnTypeImplTrait {
991 cov_mark::hit!(lower_rpit);
992 let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
993 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
994 let mut predicates: Vec<_> = bounds
996 .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
999 if !ctx.unsized_types.borrow().contains(&self_ty) {
1000 let krate = func.lookup(ctx.db.upcast()).module(ctx.db.upcast()).krate();
1001 let sized_trait = ctx
1003 .lang_item(krate, SmolStr::new_inline("sized"))
1004 .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1005 let sized_clause = sized_trait.map(|trait_id| {
1006 let clause = WhereClause::Implemented(TraitRef {
1008 substitution: Substitution::from1(Interner, self_ty.clone()),
1010 crate::wrap_empty_binders(clause)
1012 predicates.extend(sized_clause.into_iter());
1013 predicates.shrink_to_fit();
1017 ReturnTypeImplTrait { bounds: crate::make_single_type_binders(predicates) }
1021 fn count_impl_traits(type_ref: &TypeRef) -> usize {
1023 type_ref.walk(&mut |type_ref| {
1024 if matches!(type_ref, TypeRef::ImplTrait(_)) {
1031 /// Build the signature of a callable item (function, struct or enum variant).
1032 pub(crate) fn callable_item_sig(db: &dyn HirDatabase, def: CallableDefId) -> PolyFnSig {
1034 CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f),
1035 CallableDefId::StructId(s) => fn_sig_for_struct_constructor(db, s),
1036 CallableDefId::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e),
1040 pub fn associated_type_shorthand_candidates<R>(
1041 db: &dyn HirDatabase,
1044 cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
1046 named_associated_type_shorthand_candidates(db, def, res, None, cb)
1049 fn named_associated_type_shorthand_candidates<R>(
1050 db: &dyn HirDatabase,
1051 // If the type parameter is defined in an impl and we're in a method, there
1052 // might be additional where clauses to consider
1055 assoc_name: Option<Name>,
1056 mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
1058 let mut search = |t| {
1059 for t in all_super_trait_refs(db, t) {
1060 let data = db.trait_data(t.hir_trait_id());
1062 for (name, assoc_id) in &data.items {
1063 if let AssocItemId::TypeAliasId(alias) = assoc_id {
1064 if let Some(result) = cb(name, &t, *alias) {
1065 return Some(result);
1074 TypeNs::SelfType(impl_id) => search(
1075 // we're _in_ the impl -- the binders get added back later. Correct,
1076 // but it would be nice to make this more explicit
1077 db.impl_trait(impl_id)?.into_value_and_skipped_binders().0,
1079 TypeNs::GenericParam(param_id) => {
1080 let predicates = db.generic_predicates_for_param(def, param_id.into(), assoc_name);
1081 let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
1082 // FIXME: how to correctly handle higher-ranked bounds here?
1083 WhereClause::Implemented(tr) => search(
1085 .shifted_out_to(Interner, DebruijnIndex::ONE)
1086 .expect("FIXME unexpected higher-ranked trait bound"),
1090 if let Some(_) = res {
1093 // Handle `Self::Type` referring to own associated type in trait definitions
1094 if let GenericDefId::TraitId(trait_id) = param_id.parent() {
1095 let generics = generics(db.upcast(), trait_id.into());
1096 if generics.params.type_or_consts[param_id.local_id()].is_trait_self() {
1097 let trait_ref = TyBuilder::trait_ref(db, trait_id)
1098 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
1100 return search(trait_ref);
1109 /// Build the type of all specific fields of a struct or enum variant.
1110 pub(crate) fn field_types_query(
1111 db: &dyn HirDatabase,
1112 variant_id: VariantId,
1113 ) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> {
1114 let var_data = variant_id.variant_data(db.upcast());
1115 let (resolver, def): (_, GenericDefId) = match variant_id {
1116 VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()),
1117 VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()),
1118 VariantId::EnumVariantId(it) => (it.parent.resolver(db.upcast()), it.parent.into()),
1120 let generics = generics(db.upcast(), def);
1121 let mut res = ArenaMap::default();
1123 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1124 for (field_id, field_data) in var_data.fields().iter() {
1125 res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref)));
1130 /// This query exists only to be used when resolving short-hand associated types
1133 /// See the analogous query in rustc and its comment:
1134 /// <https://github.com/rust-lang/rust/blob/9150f844e2624eb013ec78ca08c1d416e6644026/src/librustc_typeck/astconv.rs#L46>
1135 /// This is a query mostly to handle cycles somewhat gracefully; e.g. the
1136 /// following bounds are disallowed: `T: Foo<U::Item>, U: Foo<T::Item>`, but
1137 /// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
1138 pub(crate) fn generic_predicates_for_param_query(
1139 db: &dyn HirDatabase,
1141 param_id: TypeOrConstParamId,
1142 assoc_name: Option<Name>,
1143 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1144 let resolver = def.resolver(db.upcast());
1146 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1147 let generics = generics(db.upcast(), def);
1148 let mut predicates: Vec<_> = resolver
1149 .where_predicates_in_scope()
1150 // we have to filter out all other predicates *first*, before attempting to lower them
1151 .filter(|pred| match pred {
1152 WherePredicate::ForLifetime { target, bound, .. }
1153 | WherePredicate::TypeBound { target, bound, .. } => {
1155 WherePredicateTypeTarget::TypeRef(type_ref) => {
1156 if ctx.lower_ty_only_param(type_ref) != Some(param_id) {
1160 &WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
1161 let target_id = TypeOrConstParamId { parent: def, local_id };
1162 if target_id != param_id {
1169 TypeBound::ForLifetime(_, path) | TypeBound::Path(path, _) => {
1170 // Only lower the bound if the trait could possibly define the associated
1171 // type we're looking for.
1173 let assoc_name = match &assoc_name {
1175 None => return true,
1177 let tr = match resolver
1178 .resolve_path_in_type_ns_fully(db.upcast(), path.mod_path())
1180 Some(TypeNs::TraitId(tr)) => tr,
1184 all_super_traits(db.upcast(), tr).iter().any(|tr| {
1185 db.trait_data(*tr).items.iter().any(|(name, item)| {
1186 matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name
1190 TypeBound::Lifetime(_) | TypeBound::Error => false,
1193 WherePredicate::Lifetime { .. } => false,
1196 ctx.lower_where_predicate(pred, true).map(|p| make_binders(db, &generics, p))
1200 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1201 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1202 let implicitly_sized_predicates =
1203 implicitly_sized_clauses(db, param_id.parent, &explicitly_unsized_tys, &subst, &resolver)
1204 .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1205 predicates.extend(implicitly_sized_predicates);
1209 pub(crate) fn generic_predicates_for_param_recover(
1210 _db: &dyn HirDatabase,
1212 _def: &GenericDefId,
1213 _param_id: &TypeOrConstParamId,
1214 _assoc_name: &Option<Name>,
1215 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1219 pub(crate) fn trait_environment_query(
1220 db: &dyn HirDatabase,
1222 ) -> Arc<TraitEnvironment> {
1223 let resolver = def.resolver(db.upcast());
1225 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Placeholder);
1226 let mut traits_in_scope = Vec::new();
1227 let mut clauses = Vec::new();
1228 for pred in resolver.where_predicates_in_scope() {
1229 for pred in ctx.lower_where_predicate(pred, false) {
1230 if let WhereClause::Implemented(tr) = &pred.skip_binders() {
1231 traits_in_scope.push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id()));
1233 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1234 clauses.push(program_clause.into_from_env_clause(Interner));
1238 let container: Option<ItemContainerId> = match def {
1239 // FIXME: is there a function for this?
1240 GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
1241 GenericDefId::AdtId(_) => None,
1242 GenericDefId::TraitId(_) => None,
1243 GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container),
1244 GenericDefId::ImplId(_) => None,
1245 GenericDefId::EnumVariantId(_) => None,
1246 GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container),
1248 if let Some(ItemContainerId::TraitId(trait_id)) = container {
1249 // add `Self: Trait<T1, T2, ...>` to the environment in trait
1250 // function default implementations (and speculative code
1251 // inside consts or type aliases)
1252 cov_mark::hit!(trait_self_implements_self);
1253 let substs = TyBuilder::placeholder_subst(db, trait_id);
1254 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
1255 let pred = WhereClause::Implemented(trait_ref);
1256 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1257 clauses.push(program_clause.into_from_env_clause(Interner));
1260 let subst = generics(db.upcast(), def).placeholder_subst(db);
1261 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1262 let implicitly_sized_clauses =
1263 implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver).map(|pred| {
1264 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1265 program_clause.into_from_env_clause(Interner)
1267 clauses.extend(implicitly_sized_clauses);
1269 let krate = def.module(db.upcast()).krate();
1271 let env = chalk_ir::Environment::new(Interner).add_clauses(Interner, clauses);
1273 Arc::new(TraitEnvironment { krate, traits_from_clauses: traits_in_scope, env })
1276 /// Resolve the where clause(s) of an item with generics.
1277 pub(crate) fn generic_predicates_query(
1278 db: &dyn HirDatabase,
1280 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1281 let resolver = def.resolver(db.upcast());
1283 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1284 let generics = generics(db.upcast(), def);
1286 let mut predicates = resolver
1287 .where_predicates_in_scope()
1289 ctx.lower_where_predicate(pred, false).map(|p| make_binders(db, &generics, p))
1291 .collect::<Vec<_>>();
1293 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1294 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1295 let implicitly_sized_predicates =
1296 implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver)
1297 .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1298 predicates.extend(implicitly_sized_predicates);
1302 /// Generate implicit `: Sized` predicates for all generics that has no `?Sized` bound.
1303 /// Exception is Self of a trait def.
1304 fn implicitly_sized_clauses<'a>(
1305 db: &dyn HirDatabase,
1307 explicitly_unsized_tys: &'a FxHashSet<Ty>,
1308 substitution: &'a Substitution,
1309 resolver: &Resolver,
1310 ) -> impl Iterator<Item = WhereClause> + 'a {
1311 let is_trait_def = matches!(def, GenericDefId::TraitId(..));
1312 let generic_args = &substitution.as_slice(Interner)[is_trait_def as usize..];
1313 let sized_trait = db
1314 .lang_item(resolver.krate(), SmolStr::new_inline("sized"))
1315 .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1317 sized_trait.into_iter().flat_map(move |sized_trait| {
1318 let implicitly_sized_tys = generic_args
1320 .filter_map(|generic_arg| generic_arg.ty(Interner))
1321 .filter(move |&self_ty| !explicitly_unsized_tys.contains(self_ty));
1322 implicitly_sized_tys.map(move |self_ty| {
1323 WhereClause::Implemented(TraitRef {
1324 trait_id: sized_trait,
1325 substitution: Substitution::from1(Interner, self_ty.clone()),
1331 /// Resolve the default type params from generics
1332 pub(crate) fn generic_defaults_query(
1333 db: &dyn HirDatabase,
1335 ) -> Arc<[Binders<chalk_ir::GenericArg<Interner>>]> {
1336 let resolver = def.resolver(db.upcast());
1338 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1339 let generic_params = generics(db.upcast(), def);
1341 let defaults = generic_params
1344 .map(|(idx, (id, p))| {
1346 TypeOrConstParamData::TypeParamData(p) => p,
1347 TypeOrConstParamData::ConstParamData(_) => {
1348 // FIXME: implement const generic defaults
1349 let val = unknown_const_as_generic(
1350 db.const_param_ty(ConstParamId::from_unchecked(id)),
1352 return crate::make_binders_with_count(db, idx, &generic_params, val);
1356 p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
1358 // Each default can only refer to previous parameters.
1359 // type variable default referring to parameter coming
1360 // after it. This is forbidden (FIXME: report
1362 ty = fallback_bound_vars(ty, idx);
1363 let val = GenericArgData::Ty(ty).intern(Interner);
1364 crate::make_binders_with_count(db, idx, &generic_params, val)
1371 pub(crate) fn generic_defaults_recover(
1372 db: &dyn HirDatabase,
1375 ) -> Arc<[Binders<crate::GenericArg>]> {
1376 let generic_params = generics(db.upcast(), *def);
1377 // FIXME: this code is not covered in tests.
1378 // we still need one default per parameter
1379 let defaults = generic_params
1382 .map(|(count, id)| {
1383 let val = match id {
1384 itertools::Either::Left(_) => {
1385 GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1387 itertools::Either::Right(id) => unknown_const_as_generic(db.const_param_ty(id)),
1389 crate::make_binders_with_count(db, count, &generic_params, val)
1396 fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1397 let data = db.function_data(def);
1398 let resolver = def.resolver(db.upcast());
1399 let ctx_params = TyLoweringContext::new(db, &resolver)
1400 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
1401 .with_type_param_mode(ParamLoweringMode::Variable);
1402 let params = data.params.iter().map(|(_, tr)| ctx_params.lower_ty(tr)).collect::<Vec<_>>();
1403 let ctx_ret = TyLoweringContext::new(db, &resolver)
1404 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1405 .with_type_param_mode(ParamLoweringMode::Variable);
1406 let ret = ctx_ret.lower_ty(&data.ret_type);
1407 let generics = generics(db.upcast(), def.into());
1408 let sig = CallableSig::from_params_and_return(params, ret, data.is_varargs());
1409 make_binders(db, &generics, sig)
1412 /// Build the declared type of a function. This should not need to look at the
1414 fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1415 let generics = generics(db.upcast(), def.into());
1416 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1420 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(Interner),
1424 /// Build the declared type of a const.
1425 fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
1426 let data = db.const_data(def);
1427 let generics = generics(db.upcast(), def.into());
1428 let resolver = def.resolver(db.upcast());
1430 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1432 make_binders(db, &generics, ctx.lower_ty(&data.type_ref))
1435 /// Build the declared type of a static.
1436 fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
1437 let data = db.static_data(def);
1438 let resolver = def.resolver(db.upcast());
1439 let ctx = TyLoweringContext::new(db, &resolver);
1441 Binders::empty(Interner, ctx.lower_ty(&data.type_ref))
1444 fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
1445 let struct_data = db.struct_data(def);
1446 let fields = struct_data.variant_data.fields();
1447 let resolver = def.resolver(db.upcast());
1449 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1450 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1451 let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
1452 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1455 /// Build the type of a tuple struct constructor.
1456 fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<Ty> {
1457 let struct_data = db.struct_data(def);
1458 if let StructKind::Unit = struct_data.variant_data.kind() {
1459 return type_for_adt(db, def.into());
1461 let generics = generics(db.upcast(), def.into());
1462 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1466 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
1470 fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
1471 let enum_data = db.enum_data(def.parent);
1472 let var_data = &enum_data.variants[def.local_id];
1473 let fields = var_data.variant_data.fields();
1474 let resolver = def.parent.resolver(db.upcast());
1476 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1477 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1478 let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
1479 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1482 /// Build the type of a tuple enum variant constructor.
1483 fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> Binders<Ty> {
1484 let enum_data = db.enum_data(def.parent);
1485 let var_data = &enum_data.variants[def.local_id].variant_data;
1486 if let StructKind::Unit = var_data.kind() {
1487 return type_for_adt(db, def.parent.into());
1489 let generics = generics(db.upcast(), def.parent.into());
1490 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1494 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(Interner),
1498 fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1499 let generics = generics(db.upcast(), adt.into());
1500 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1501 let ty = TyKind::Adt(crate::AdtId(adt), subst).intern(Interner);
1502 make_binders(db, &generics, ty)
1505 fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1506 let generics = generics(db.upcast(), t.into());
1507 let resolver = t.resolver(db.upcast());
1509 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1510 if db.type_alias_data(t).is_extern {
1511 Binders::empty(Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner))
1513 let type_ref = &db.type_alias_data(t).type_ref;
1514 let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
1515 make_binders(db, &generics, inner)
1519 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1520 pub enum CallableDefId {
1521 FunctionId(FunctionId),
1523 EnumVariantId(EnumVariantId),
1525 impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
1527 impl CallableDefId {
1528 pub fn krate(self, db: &dyn HirDatabase) -> CrateId {
1529 let db = db.upcast();
1531 CallableDefId::FunctionId(f) => f.lookup(db).module(db),
1532 CallableDefId::StructId(s) => s.lookup(db).container,
1533 CallableDefId::EnumVariantId(e) => e.parent.lookup(db).container,
1539 impl From<CallableDefId> for GenericDefId {
1540 fn from(def: CallableDefId) -> GenericDefId {
1542 CallableDefId::FunctionId(f) => f.into(),
1543 CallableDefId::StructId(s) => s.into(),
1544 CallableDefId::EnumVariantId(e) => e.into(),
1549 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1551 BuiltinType(BuiltinType),
1553 TypeAliasId(TypeAliasId),
1555 impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
1557 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1558 pub enum ValueTyDefId {
1559 FunctionId(FunctionId),
1562 EnumVariantId(EnumVariantId),
1566 impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
1568 /// Build the declared type of an item. This depends on the namespace; e.g. for
1569 /// `struct Foo(usize)`, we have two types: The type of the struct itself, and
1570 /// the constructor function `(usize) -> Foo` which lives in the values
1572 pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
1574 TyDefId::BuiltinType(it) => Binders::empty(Interner, TyBuilder::builtin(it)),
1575 TyDefId::AdtId(it) => type_for_adt(db, it),
1576 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
1580 pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> {
1581 let generics = match *def {
1582 TyDefId::BuiltinType(_) => return Binders::empty(Interner, TyKind::Error.intern(Interner)),
1583 TyDefId::AdtId(it) => generics(db.upcast(), it.into()),
1584 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()),
1586 make_binders(db, &generics, TyKind::Error.intern(Interner))
1589 pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
1591 ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
1592 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
1593 ValueTyDefId::UnionId(it) => type_for_adt(db, it.into()),
1594 ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
1595 ValueTyDefId::ConstId(it) => type_for_const(db, it),
1596 ValueTyDefId::StaticId(it) => type_for_static(db, it),
1600 pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> {
1601 let impl_loc = impl_id.lookup(db.upcast());
1602 let impl_data = db.impl_data(impl_id);
1603 let resolver = impl_id.resolver(db.upcast());
1604 let _cx = stdx::panic_context::enter(format!(
1605 "impl_self_ty_query({:?} -> {:?} -> {:?})",
1606 impl_id, impl_loc, impl_data
1608 let generics = generics(db.upcast(), impl_id.into());
1610 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1611 make_binders(db, &generics, ctx.lower_ty(&impl_data.self_ty))
1614 // returns None if def is a type arg
1615 pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
1616 let parent_data = db.generic_params(def.parent());
1617 let data = &parent_data.type_or_consts[def.local_id()];
1618 let resolver = def.parent().resolver(db.upcast());
1619 let ctx = TyLoweringContext::new(db, &resolver);
1621 TypeOrConstParamData::TypeParamData(_) => {
1623 Ty::new(Interner, TyKind::Error)
1625 TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(&d.ty),
1629 pub(crate) fn impl_self_ty_recover(
1630 db: &dyn HirDatabase,
1634 let generics = generics(db.upcast(), (*impl_id).into());
1635 make_binders(db, &generics, TyKind::Error.intern(Interner))
1638 pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
1639 let impl_loc = impl_id.lookup(db.upcast());
1640 let impl_data = db.impl_data(impl_id);
1641 let resolver = impl_id.resolver(db.upcast());
1642 let _cx = stdx::panic_context::enter(format!(
1643 "impl_trait_query({:?} -> {:?} -> {:?})",
1644 impl_id, impl_loc, impl_data
1647 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1648 let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
1649 let target_trait = impl_data.target_trait.as_ref()?;
1650 Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
1653 pub(crate) fn return_type_impl_traits(
1654 db: &dyn HirDatabase,
1655 def: hir_def::FunctionId,
1656 ) -> Option<Arc<Binders<ReturnTypeImplTraits>>> {
1657 // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
1658 let data = db.function_data(def);
1659 let resolver = def.resolver(db.upcast());
1660 let ctx_ret = TyLoweringContext::new(db, &resolver)
1661 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1662 .with_type_param_mode(ParamLoweringMode::Variable);
1663 let _ret = (&ctx_ret).lower_ty(&data.ret_type);
1664 let generics = generics(db.upcast(), def.into());
1665 let return_type_impl_traits =
1666 ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() };
1667 if return_type_impl_traits.impl_traits.is_empty() {
1670 Some(Arc::new(make_binders(db, &generics, return_type_impl_traits)))
1674 pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mutability {
1676 hir_def::type_ref::Mutability::Shared => Mutability::Not,
1677 hir_def::type_ref::Mutability::Mut => Mutability::Mut,
1681 /// Checks if the provided generic arg matches its expected kind, then lower them via
1682 /// provided closures. Use unknown if there was kind mismatch.
1684 /// Returns `Some` of the lowered generic arg. `None` if the provided arg is a lifetime.
1685 pub(crate) fn generic_arg_to_chalk<'a, T>(
1686 db: &dyn HirDatabase,
1687 kind_id: Either<TypeParamId, ConstParamId>,
1688 arg: &'a GenericArg,
1690 for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a,
1691 for_const: impl FnOnce(&mut T, &ConstScalarOrPath, Ty) -> Const + 'a,
1692 ) -> Option<crate::GenericArg> {
1693 let kind = match kind_id {
1694 Either::Left(_) => ParamKind::Type,
1695 Either::Right(id) => {
1696 let ty = db.const_param_ty(id);
1697 ParamKind::Const(ty)
1700 Some(match (arg, kind) {
1701 (GenericArg::Type(type_ref), ParamKind::Type) => {
1702 let ty = for_type(this, type_ref);
1703 GenericArgData::Ty(ty).intern(Interner)
1705 (GenericArg::Const(c), ParamKind::Const(c_ty)) => {
1706 GenericArgData::Const(for_const(this, c, c_ty)).intern(Interner)
1708 (GenericArg::Const(_), ParamKind::Type) => {
1709 GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1711 (GenericArg::Type(t), ParamKind::Const(c_ty)) => {
1712 // We want to recover simple idents, which parser detects them
1713 // as types. Maybe here is not the best place to do it, but
1715 if let TypeRef::Path(p) = t {
1716 let p = p.mod_path();
1717 if p.kind == PathKind::Plain {
1718 if let [n] = p.segments() {
1719 let c = ConstScalarOrPath::Path(n.clone());
1721 GenericArgData::Const(for_const(this, &c, c_ty)).intern(Interner),
1726 unknown_const_as_generic(c_ty)
1728 (GenericArg::Lifetime(_), _) => return None,
1732 pub(crate) fn const_or_path_to_chalk(
1733 db: &dyn HirDatabase,
1734 resolver: &Resolver,
1736 value: &ConstScalarOrPath,
1737 mode: ParamLoweringMode,
1738 args: impl FnOnce() -> Generics,
1739 debruijn: DebruijnIndex,
1742 ConstScalarOrPath::Scalar(s) => intern_const_scalar(s.clone(), expected_ty),
1743 ConstScalarOrPath::Path(n) => {
1744 let path = ModPath::from_segments(PathKind::Plain, Some(n.clone()));
1745 path_to_const(db, resolver, &path, mode, args, debruijn)
1746 .unwrap_or_else(|| unknown_const(expected_ty))
1751 /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
1752 /// num_vars_to_keep) by `TyKind::Unknown`.
1753 fn fallback_bound_vars<T: TypeFoldable<Interner> + HasInterner<Interner = Interner>>(
1755 num_vars_to_keep: usize,
1757 crate::fold_free_vars(
1760 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1761 TyKind::Error.intern(Interner)
1763 bound.shifted_in_from(binders).to_ty(Interner)
1766 |ty, bound, binders| {
1767 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1768 unknown_const(ty.clone())
1770 bound.shifted_in_from(binders).to_const(Interner, ty)