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};
48 intern_const_scalar_with_type, path_to_const, unknown_const, unknown_const_as_generic,
53 static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
55 utils::{all_super_trait_refs, associated_type_by_name_including_super_traits, generics},
56 AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, DebruijnIndex, DynTy, FnPointer,
57 FnSig, FnSubst, GenericArgData, ImplTraitId, Interner, ParamKind, PolyFnSig, ProjectionTy,
58 QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits,
59 Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
63 pub struct TyLoweringContext<'a> {
64 pub db: &'a dyn HirDatabase,
65 pub resolver: &'a Resolver,
66 in_binders: DebruijnIndex,
67 /// Note: Conceptually, it's thinkable that we could be in a location where
68 /// some type params should be represented as placeholders, and others
69 /// should be converted to variables. I think in practice, this isn't
70 /// possible currently, so this should be fine for now.
71 pub type_param_mode: ParamLoweringMode,
72 pub impl_trait_mode: ImplTraitLoweringMode,
73 impl_trait_counter: Cell<u16>,
74 /// When turning `impl Trait` into opaque types, we have to collect the
75 /// bounds at the same time to get the IDs correct (without becoming too
76 /// complicated). I don't like using interior mutability (as for the
77 /// counter), but I've tried and failed to make the lifetimes work for
78 /// passing around a `&mut TyLoweringContext`. The core problem is that
79 /// we're grouping the mutable data (the counter and this field) together
80 /// with the immutable context (the references to the DB and resolver).
81 /// Splitting this up would be a possible fix.
82 opaque_type_data: RefCell<Vec<ReturnTypeImplTrait>>,
83 expander: RefCell<Option<Expander>>,
84 /// Tracks types with explicit `?Sized` bounds.
85 pub(crate) unsized_types: RefCell<FxHashSet<Ty>>,
88 impl<'a> TyLoweringContext<'a> {
89 pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver) -> Self {
90 let impl_trait_counter = Cell::new(0);
91 let impl_trait_mode = ImplTraitLoweringMode::Disallowed;
92 let type_param_mode = ParamLoweringMode::Placeholder;
93 let in_binders = DebruijnIndex::INNERMOST;
94 let opaque_type_data = RefCell::new(Vec::new());
103 expander: RefCell::new(None),
104 unsized_types: RefCell::default(),
108 pub fn with_debruijn<T>(
110 debruijn: DebruijnIndex,
111 f: impl FnOnce(&TyLoweringContext) -> T,
113 let opaque_ty_data_vec = self.opaque_type_data.take();
114 let expander = self.expander.take();
115 let unsized_types = self.unsized_types.take();
117 in_binders: debruijn,
118 impl_trait_counter: Cell::new(self.impl_trait_counter.get()),
119 opaque_type_data: RefCell::new(opaque_ty_data_vec),
120 expander: RefCell::new(expander),
121 unsized_types: RefCell::new(unsized_types),
124 let result = f(&new_ctx);
125 self.impl_trait_counter.set(new_ctx.impl_trait_counter.get());
126 self.opaque_type_data.replace(new_ctx.opaque_type_data.into_inner());
127 self.expander.replace(new_ctx.expander.into_inner());
128 self.unsized_types.replace(new_ctx.unsized_types.into_inner());
132 pub fn with_shifted_in<T>(
134 debruijn: DebruijnIndex,
135 f: impl FnOnce(&TyLoweringContext) -> T,
137 self.with_debruijn(self.in_binders.shifted_in_from(debruijn), f)
140 pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
141 Self { impl_trait_mode, ..self }
144 pub fn with_type_param_mode(self, type_param_mode: ParamLoweringMode) -> Self {
145 Self { type_param_mode, ..self }
149 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
150 pub enum ImplTraitLoweringMode {
151 /// `impl Trait` gets lowered into an opaque type that doesn't unify with
152 /// anything except itself. This is used in places where values flow 'out',
153 /// i.e. for arguments of the function we're currently checking, and return
154 /// types of functions we're calling.
156 /// `impl Trait` gets lowered into a type variable. Used for argument
157 /// position impl Trait when inside the respective function, since it allows
158 /// us to support that without Chalk.
160 /// `impl Trait` gets lowered into a variable that can unify with some
161 /// type. This is used in places where values flow 'in', i.e. for arguments
162 /// of functions we're calling, and the return type of the function we're
163 /// currently checking.
165 /// `impl Trait` is disallowed and will be an error.
169 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
170 pub enum ParamLoweringMode {
175 impl<'a> TyLoweringContext<'a> {
176 pub fn lower_ty(&self, type_ref: &TypeRef) -> Ty {
177 self.lower_ty_ext(type_ref).0
180 fn generics(&self) -> Generics {
185 .expect("there should be generics if there's a generic param"),
189 pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
191 let ty = match type_ref {
192 TypeRef::Never => TyKind::Never.intern(Interner),
193 TypeRef::Tuple(inner) => {
194 let inner_tys = inner.iter().map(|tr| self.lower_ty(tr));
195 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(Interner, inner_tys))
198 TypeRef::Path(path) => {
199 let (ty, res_) = self.lower_path(path);
203 TypeRef::RawPtr(inner, mutability) => {
204 let inner_ty = self.lower_ty(inner);
205 TyKind::Raw(lower_to_chalk_mutability(*mutability), inner_ty).intern(Interner)
207 TypeRef::Array(inner, len) => {
208 let inner_ty = self.lower_ty(inner);
209 let const_len = const_or_path_to_chalk(
214 self.type_param_mode,
219 TyKind::Array(inner_ty, const_len).intern(Interner)
221 TypeRef::Slice(inner) => {
222 let inner_ty = self.lower_ty(inner);
223 TyKind::Slice(inner_ty).intern(Interner)
225 TypeRef::Reference(inner, _, mutability) => {
226 let inner_ty = self.lower_ty(inner);
227 let lifetime = static_lifetime();
228 TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty)
231 TypeRef::Placeholder => TyKind::Error.intern(Interner),
232 TypeRef::Fn(params, is_varargs) => {
233 let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
234 Substitution::from_iter(Interner, params.iter().map(|(_, tr)| ctx.lower_ty(tr)))
236 TyKind::Function(FnPointer {
237 num_binders: 0, // FIXME lower `for<'a> fn()` correctly
238 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
239 substitution: FnSubst(substs),
243 TypeRef::DynTrait(bounds) => {
245 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
246 let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
247 QuantifiedWhereClauses::from_iter(
249 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
252 let bounds = crate::make_single_type_binders(bounds);
253 TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
255 TypeRef::ImplTrait(bounds) => {
256 match self.impl_trait_mode {
257 ImplTraitLoweringMode::Opaque => {
258 let idx = self.impl_trait_counter.get();
259 self.impl_trait_counter.set(idx + 1);
260 let func = match self.resolver.generic_def() {
261 Some(GenericDefId::FunctionId(f)) => f,
262 _ => panic!("opaque impl trait lowering in non-function"),
265 assert!(idx as usize == self.opaque_type_data.borrow().len());
266 // this dance is to make sure the data is in the right
267 // place even if we encounter more opaque types while
268 // lowering the bounds
269 self.opaque_type_data.borrow_mut().push(ReturnTypeImplTrait {
270 bounds: crate::make_single_type_binders(Vec::new()),
272 // We don't want to lower the bounds inside the binders
273 // we're currently in, because they don't end up inside
274 // those binders. E.g. when we have `impl Trait<impl
275 // OtherTrait<T>>`, the `impl OtherTrait<T>` can't refer
276 // to the self parameter from `impl Trait`, and the
277 // bounds aren't actually stored nested within each
278 // other, but separately. So if the `T` refers to a type
279 // parameter of the outer function, it's just one binder
280 // away instead of two.
281 let actual_opaque_type_data = self
282 .with_debruijn(DebruijnIndex::INNERMOST, |ctx| {
283 ctx.lower_impl_trait(bounds, func)
285 self.opaque_type_data.borrow_mut()[idx as usize] = actual_opaque_type_data;
287 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx);
288 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
289 let generics = generics(self.db.upcast(), func.into());
290 let parameters = generics.bound_vars_subst(self.db, self.in_binders);
291 TyKind::OpaqueType(opaque_ty_id, parameters).intern(Interner)
293 ImplTraitLoweringMode::Param => {
294 let idx = self.impl_trait_counter.get();
295 // FIXME we're probably doing something wrong here
296 self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
297 if let Some(def) = self.resolver.generic_def() {
298 let generics = generics(self.db.upcast(), def);
301 .filter(|(_, data)| {
304 TypeOrConstParamData::TypeParamData(data)
305 if data.provenance == TypeParamProvenance::ArgumentImplTrait
309 .map_or(TyKind::Error, |(id, _)| {
310 TyKind::Placeholder(to_placeholder_idx(self.db, id))
312 param.intern(Interner)
314 TyKind::Error.intern(Interner)
317 ImplTraitLoweringMode::Variable => {
318 let idx = self.impl_trait_counter.get();
319 // FIXME we're probably doing something wrong here
320 self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
327 ) = if let Some(def) = self.resolver.generic_def() {
328 let generics = generics(self.db.upcast(), def);
329 generics.provenance_split()
333 TyKind::BoundVar(BoundVar::new(
335 idx as usize + parent_params + self_params + list_params + const_params,
339 ImplTraitLoweringMode::Disallowed => {
340 // FIXME: report error
341 TyKind::Error.intern(Interner)
345 TypeRef::Macro(macro_call) => {
346 let (expander, recursion_start) = {
347 let mut expander = self.expander.borrow_mut();
348 if expander.is_some() {
349 (Some(expander), false)
351 *expander = Some(Expander::new(
354 self.resolver.module(),
356 (Some(expander), true)
359 let ty = if let Some(mut expander) = expander {
360 let expander_mut = expander.as_mut().unwrap();
361 let macro_call = macro_call.to_node(self.db.upcast());
362 match expander_mut.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
363 Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
365 LowerCtx::new(self.db.upcast(), expander_mut.current_file_id());
366 let type_ref = TypeRef::from_ast(&ctx, expanded);
369 let ty = self.lower_ty(&type_ref);
375 .exit(self.db.upcast(), mark);
384 *self.expander.borrow_mut() = None;
386 ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
388 TypeRef::Error => TyKind::Error.intern(Interner),
393 /// This is only for `generic_predicates_for_param`, where we can't just
394 /// lower the self types of the predicates since that could lead to cycles.
395 /// So we just check here if the `type_ref` resolves to a generic param, and which.
396 fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeOrConstParamId> {
397 let path = match type_ref {
398 TypeRef::Path(path) => path,
401 if path.type_anchor().is_some() {
404 if path.segments().len() > 1 {
408 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
409 Some((it, None)) => it,
413 TypeNs::GenericParam(param_id) => Some(param_id.into()),
418 pub(crate) fn lower_ty_relative_path(
421 // We need the original resolution to lower `Self::AssocTy` correctly
423 remaining_segments: PathSegments<'_>,
424 ) -> (Ty, Option<TypeNs>) {
425 match remaining_segments.len() {
428 // resolve unselected assoc types
429 let segment = remaining_segments.first().unwrap();
430 (self.select_associated_type(res, segment), None)
433 // FIXME report error (ambiguous associated type)
434 (TyKind::Error.intern(Interner), None)
439 pub(crate) fn lower_partly_resolved_path(
442 resolved_segment: PathSegment<'_>,
443 remaining_segments: PathSegments<'_>,
445 ) -> (Ty, Option<TypeNs>) {
446 let ty = match resolution {
447 TypeNs::TraitId(trait_) => {
448 let ty = match remaining_segments.len() {
451 self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None);
452 let segment = remaining_segments.first().unwrap();
455 .trait_data(trait_ref.hir_trait_id())
456 .associated_type_by_name(segment.name);
458 Some(associated_ty) => {
459 // FIXME handle type parameters on the segment
460 TyKind::Alias(AliasTy::Projection(ProjectionTy {
461 associated_ty_id: to_assoc_type_id(associated_ty),
462 substitution: trait_ref.substitution,
467 // FIXME: report error (associated type not found)
468 TyKind::Error.intern(Interner)
474 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
477 let trait_ref = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
478 ctx.lower_trait_ref_from_resolved_path(
485 bounds: crate::make_single_type_binders(
486 QuantifiedWhereClauses::from_iter(
488 Some(crate::wrap_empty_binders(WhereClause::Implemented(
493 lifetime: static_lifetime(),
495 TyKind::Dyn(dyn_ty).intern(Interner)
498 // FIXME report error (ambiguous associated type)
499 TyKind::Error.intern(Interner)
504 TypeNs::GenericParam(param_id) => {
505 let generics = generics(
507 self.resolver.generic_def().expect("generics in scope"),
509 match self.type_param_mode {
510 ParamLoweringMode::Placeholder => {
511 TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into()))
513 ParamLoweringMode::Variable => {
514 let idx = generics.param_idx(param_id.into()).expect("matching generics");
515 TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
520 TypeNs::SelfType(impl_id) => {
521 let generics = generics(self.db.upcast(), impl_id.into());
522 let substs = match self.type_param_mode {
523 ParamLoweringMode::Placeholder => generics.placeholder_subst(self.db),
524 ParamLoweringMode::Variable => {
525 generics.bound_vars_subst(self.db, self.in_binders)
528 self.db.impl_self_ty(impl_id).substitute(Interner, &substs)
530 TypeNs::AdtSelfType(adt) => {
531 let generics = generics(self.db.upcast(), adt.into());
532 let substs = match self.type_param_mode {
533 ParamLoweringMode::Placeholder => generics.placeholder_subst(self.db),
534 ParamLoweringMode::Variable => {
535 generics.bound_vars_subst(self.db, self.in_binders)
538 self.db.ty(adt.into()).substitute(Interner, &substs)
541 TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args),
542 TypeNs::BuiltinType(it) => {
543 self.lower_path_inner(resolved_segment, it.into(), infer_args)
545 TypeNs::TypeAliasId(it) => {
546 self.lower_path_inner(resolved_segment, it.into(), infer_args)
548 // FIXME: report error
549 TypeNs::EnumVariantId(_) => return (TyKind::Error.intern(Interner), None),
551 self.lower_ty_relative_path(ty, Some(resolution), remaining_segments)
554 pub(crate) fn lower_path(&self, path: &Path) -> (Ty, Option<TypeNs>) {
555 // Resolve the path (in type namespace)
556 if let Some(type_ref) = path.type_anchor() {
557 let (ty, res) = self.lower_ty_ext(type_ref);
558 return self.lower_ty_relative_path(ty, res, path.segments());
560 let (resolution, remaining_index) =
561 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
563 None => return (TyKind::Error.intern(Interner), None),
565 let (resolved_segment, remaining_segments) = match remaining_index {
567 path.segments().last().expect("resolved path has at least one element"),
570 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)),
572 self.lower_partly_resolved_path(resolution, resolved_segment, remaining_segments, false)
575 fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
576 let (def, res) = match (self.resolver.generic_def(), res) {
577 (Some(def), Some(res)) => (def, res),
578 _ => return TyKind::Error.intern(Interner),
580 let ty = named_associated_type_shorthand_candidates(
584 Some(segment.name.clone()),
585 move |name, t, associated_ty| {
586 if name == segment.name {
587 let substs = match self.type_param_mode {
588 ParamLoweringMode::Placeholder => {
589 // if we're lowering to placeholders, we have to put
591 let generics = generics(
595 .expect("there should be generics if there's a generic param"),
597 let s = generics.placeholder_subst(self.db);
598 s.apply(t.substitution.clone(), Interner)
600 ParamLoweringMode::Variable => t.substitution.clone(),
602 // We need to shift in the bound vars, since
603 // associated_type_shorthand_candidates does not do that
604 let substs = substs.shifted_in_from(Interner, self.in_binders);
605 // FIXME handle type parameters on the segment
607 TyKind::Alias(AliasTy::Projection(ProjectionTy {
608 associated_ty_id: to_assoc_type_id(associated_ty),
609 substitution: substs,
619 ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
624 segment: PathSegment<'_>,
628 let generic_def = match typeable {
629 TyDefId::BuiltinType(_) => None,
630 TyDefId::AdtId(it) => Some(it.into()),
631 TyDefId::TypeAliasId(it) => Some(it.into()),
633 let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None);
634 self.db.ty(typeable).substitute(Interner, &substs)
637 /// Collect generic arguments from a path into a `Substs`. See also
638 /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
639 pub(super) fn substs_from_path(
642 // Note that we don't call `db.value_type(resolved)` here,
643 // `ValueTyDefId` is just a convenient way to pass generics and
644 // special-case enum variants
645 resolved: ValueTyDefId,
648 let last = path.segments().last().expect("path should have at least one segment");
649 let (segment, generic_def) = match resolved {
650 ValueTyDefId::FunctionId(it) => (last, Some(it.into())),
651 ValueTyDefId::StructId(it) => (last, Some(it.into())),
652 ValueTyDefId::UnionId(it) => (last, Some(it.into())),
653 ValueTyDefId::ConstId(it) => (last, Some(it.into())),
654 ValueTyDefId::StaticId(_) => (last, None),
655 ValueTyDefId::EnumVariantId(var) => {
656 // the generic args for an enum variant may be either specified
657 // on the segment referring to the enum, or on the segment
658 // referring to the variant. So `Option::<T>::None` and
659 // `Option::None::<T>` are both allowed (though the former is
660 // preferred). See also `def_ids_for_path_segments` in rustc.
661 let len = path.segments().len();
662 let penultimate = len.checked_sub(2).and_then(|idx| path.segments().get(idx));
663 let segment = match penultimate {
664 Some(segment) if segment.args_and_bindings.is_some() => segment,
667 (segment, Some(var.parent.into()))
670 self.substs_from_path_segment(segment, generic_def, infer_args, None)
673 fn substs_from_path_segment(
675 segment: PathSegment<'_>,
676 def_generic: Option<GenericDefId>,
678 explicit_self_ty: Option<Ty>,
680 let mut substs = Vec::new();
681 let def_generics = if let Some(def) = def_generic {
682 generics(self.db.upcast(), def)
684 return Substitution::empty(Interner);
686 let (parent_params, self_params, type_params, const_params, impl_trait_params) =
687 def_generics.provenance_split();
689 parent_params + self_params + type_params + const_params + impl_trait_params;
691 let ty_error = GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner);
693 let mut def_generic_iter = def_generics.iter_id();
695 for _ in 0..parent_params {
696 if let Some(eid) = def_generic_iter.next() {
698 Either::Left(_) => substs.push(ty_error.clone()),
699 Either::Right(x) => {
700 substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
706 let fill_self_params = || {
707 for x in explicit_self_ty
709 .map(|x| GenericArgData::Ty(x).intern(Interner))
710 .chain(iter::repeat(ty_error.clone()))
713 if let Some(id) = def_generic_iter.next() {
714 assert!(id.is_left());
719 let mut had_explicit_args = false;
721 if let Some(generic_args) = &segment.args_and_bindings {
722 if !generic_args.has_self_type {
725 let expected_num = if generic_args.has_self_type {
726 self_params + type_params + const_params
728 type_params + const_params
730 let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
731 // if args are provided, it should be all of them, but we can't rely on that
732 for arg in generic_args
735 .filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
739 if let Some(id) = def_generic_iter.next() {
740 if let Some(x) = generic_arg_to_chalk(
745 |_, type_ref| self.lower_ty(type_ref),
747 const_or_path_to_chalk(
752 self.type_param_mode,
758 had_explicit_args = true;
761 // we just filtered them out
762 never!("Unexpected lifetime argument");
770 // handle defaults. In expression or pattern path segments without
771 // explicitly specified type arguments, missing type arguments are inferred
772 // (i.e. defaults aren't used).
773 if !infer_args || had_explicit_args {
774 if let Some(def_generic) = def_generic {
775 let defaults = self.db.generic_defaults(def_generic);
776 assert_eq!(total_len, defaults.len());
778 for default_ty in defaults.iter().skip(substs.len()) {
779 // each default can depend on the previous parameters
780 let substs_so_far = Substitution::from_iter(Interner, substs.clone());
781 if let Some(_id) = def_generic_iter.next() {
782 substs.push(default_ty.clone().substitute(Interner, &substs_so_far));
788 // add placeholders for args that were not provided
789 // FIXME: emit diagnostics in contexts where this is not allowed
790 for eid in def_generic_iter {
792 Either::Left(_) => substs.push(ty_error.clone()),
793 Either::Right(x) => {
794 substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
798 // If this assert fails, it means you pushed into subst but didn't call .next() of def_generic_iter
799 assert_eq!(substs.len(), total_len);
801 Substitution::from_iter(Interner, substs)
804 fn lower_trait_ref_from_path(
807 explicit_self_ty: Option<Ty>,
808 ) -> Option<TraitRef> {
810 match self.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), path.mod_path())? {
811 TypeNs::TraitId(tr) => tr,
814 let segment = path.segments().last().expect("path should have at least one segment");
815 Some(self.lower_trait_ref_from_resolved_path(resolved, segment, explicit_self_ty))
818 pub(crate) fn lower_trait_ref_from_resolved_path(
821 segment: PathSegment<'_>,
822 explicit_self_ty: Option<Ty>,
824 let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
825 TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
830 trait_ref: &HirTraitRef,
831 explicit_self_ty: Option<Ty>,
832 ) -> Option<TraitRef> {
833 self.lower_trait_ref_from_path(&trait_ref.path, explicit_self_ty)
836 fn trait_ref_substs_from_path(
838 segment: PathSegment<'_>,
840 explicit_self_ty: Option<Ty>,
842 self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
845 pub(crate) fn lower_where_predicate(
847 where_predicate: &'a WherePredicate,
848 ignore_bindings: bool,
849 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
850 match where_predicate {
851 WherePredicate::ForLifetime { target, bound, .. }
852 | WherePredicate::TypeBound { target, bound } => {
853 let self_ty = match target {
854 WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
855 WherePredicateTypeTarget::TypeOrConstParam(param_id) => {
856 let generic_def = self.resolver.generic_def().expect("generics in scope");
857 let generics = generics(self.db.upcast(), generic_def);
858 let param_id = hir_def::TypeOrConstParamId {
862 let placeholder = to_placeholder_idx(self.db, param_id);
863 match self.type_param_mode {
864 ParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder),
865 ParamLoweringMode::Variable => {
866 let idx = generics.param_idx(param_id).expect("matching generics");
867 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
873 self.lower_type_bound(bound, self_ty, ignore_bindings)
877 WherePredicate::Lifetime { .. } => vec![].into_iter(),
881 pub(crate) fn lower_type_bound(
883 bound: &'a TypeBound,
885 ignore_bindings: bool,
886 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
887 let mut bindings = None;
888 let trait_ref = match bound {
889 TypeBound::Path(path, TraitBoundModifier::None) => {
890 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
894 // ignore `T: Drop` or `T: Destruct` bounds.
895 // - `T: ~const Drop` has a special meaning in Rust 1.61 that we don't implement.
896 // (So ideally, we'd only ignore `~const Drop` here)
897 // - `Destruct` impls are built-in in 1.62 (current nightlies as of 08-04-2022), so until
898 // the builtin impls are supported by Chalk, we ignore them here.
899 if let Some(lang) = lang_attr(self.db.upcast(), tr.hir_trait_id()) {
900 if lang == "drop" || lang == "destruct" {
906 .map(WhereClause::Implemented)
907 .map(crate::wrap_empty_binders)
909 TypeBound::Path(path, TraitBoundModifier::Maybe) => {
910 let sized_trait = self
912 .lang_item(self.resolver.krate(), SmolStr::new_inline("sized"))
913 .and_then(|lang_item| lang_item.as_trait());
914 // Don't lower associated type bindings as the only possible relaxed trait bound
915 // `?Sized` has no of them.
916 // If we got another trait here ignore the bound completely.
918 .lower_trait_ref_from_path(path, Some(self_ty.clone()))
919 .map(|trait_ref| trait_ref.hir_trait_id());
920 if trait_id == sized_trait {
921 self.unsized_types.borrow_mut().insert(self_ty);
925 TypeBound::ForLifetime(_, path) => {
926 // FIXME Don't silently drop the hrtb lifetimes here
927 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
928 bindings.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
930 TypeBound::Lifetime(_) => None,
931 TypeBound::Error => None,
933 trait_ref.into_iter().chain(
936 .filter(move |_| !ignore_bindings)
937 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)),
941 fn assoc_type_bindings_from_type_bound(
943 bound: &'a TypeBound,
945 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
946 let last_segment = match bound {
947 TypeBound::Path(path, TraitBoundModifier::None) | TypeBound::ForLifetime(_, path) => {
948 path.segments().last()
950 TypeBound::Path(_, TraitBoundModifier::Maybe)
952 | TypeBound::Lifetime(_) => None,
956 .filter_map(|segment| segment.args_and_bindings)
957 .flat_map(|args_and_bindings| &args_and_bindings.bindings)
958 .flat_map(move |binding| {
959 let found = associated_type_by_name_including_super_traits(
964 let (super_trait_ref, associated_ty) = match found {
965 None => return SmallVec::new(),
968 let projection_ty = ProjectionTy {
969 associated_ty_id: to_assoc_type_id(associated_ty),
970 substitution: super_trait_ref.substitution,
972 let mut preds: SmallVec<[_; 1]> = SmallVec::with_capacity(
973 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
975 if let Some(type_ref) = &binding.type_ref {
976 let ty = self.lower_ty(type_ref);
978 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
979 preds.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
981 for bound in &binding.bounds {
982 preds.extend(self.lower_type_bound(
984 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(Interner),
994 bounds: &[Interned<TypeBound>],
996 ) -> ReturnTypeImplTrait {
997 cov_mark::hit!(lower_rpit);
998 let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
999 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
1000 let mut predicates: Vec<_> = bounds
1002 .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
1005 if !ctx.unsized_types.borrow().contains(&self_ty) {
1006 let krate = func.lookup(ctx.db.upcast()).module(ctx.db.upcast()).krate();
1007 let sized_trait = ctx
1009 .lang_item(krate, SmolStr::new_inline("sized"))
1010 .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1011 let sized_clause = sized_trait.map(|trait_id| {
1012 let clause = WhereClause::Implemented(TraitRef {
1014 substitution: Substitution::from1(Interner, self_ty.clone()),
1016 crate::wrap_empty_binders(clause)
1018 predicates.extend(sized_clause.into_iter());
1019 predicates.shrink_to_fit();
1023 ReturnTypeImplTrait { bounds: crate::make_single_type_binders(predicates) }
1027 fn count_impl_traits(type_ref: &TypeRef) -> usize {
1029 type_ref.walk(&mut |type_ref| {
1030 if matches!(type_ref, TypeRef::ImplTrait(_)) {
1037 /// Build the signature of a callable item (function, struct or enum variant).
1038 pub fn callable_item_sig(db: &dyn HirDatabase, def: CallableDefId) -> PolyFnSig {
1040 CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f),
1041 CallableDefId::StructId(s) => fn_sig_for_struct_constructor(db, s),
1042 CallableDefId::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e),
1046 pub fn associated_type_shorthand_candidates<R>(
1047 db: &dyn HirDatabase,
1050 cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
1052 named_associated_type_shorthand_candidates(db, def, res, None, cb)
1055 fn named_associated_type_shorthand_candidates<R>(
1056 db: &dyn HirDatabase,
1057 // If the type parameter is defined in an impl and we're in a method, there
1058 // might be additional where clauses to consider
1061 assoc_name: Option<Name>,
1062 mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
1064 let mut search = |t| {
1065 for t in all_super_trait_refs(db, t) {
1066 let data = db.trait_data(t.hir_trait_id());
1068 for (name, assoc_id) in &data.items {
1069 if let AssocItemId::TypeAliasId(alias) = assoc_id {
1070 if let Some(result) = cb(name, &t, *alias) {
1071 return Some(result);
1080 TypeNs::SelfType(impl_id) => search(
1081 // we're _in_ the impl -- the binders get added back later. Correct,
1082 // but it would be nice to make this more explicit
1083 db.impl_trait(impl_id)?.into_value_and_skipped_binders().0,
1085 TypeNs::GenericParam(param_id) => {
1086 let predicates = db.generic_predicates_for_param(def, param_id.into(), assoc_name);
1087 let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
1088 // FIXME: how to correctly handle higher-ranked bounds here?
1089 WhereClause::Implemented(tr) => search(
1091 .shifted_out_to(Interner, DebruijnIndex::ONE)
1092 .expect("FIXME unexpected higher-ranked trait bound"),
1096 if let Some(_) = res {
1099 // Handle `Self::Type` referring to own associated type in trait definitions
1100 if let GenericDefId::TraitId(trait_id) = param_id.parent() {
1101 let generics = generics(db.upcast(), trait_id.into());
1102 if generics.params.type_or_consts[param_id.local_id()].is_trait_self() {
1103 let trait_ref = TyBuilder::trait_ref(db, trait_id)
1104 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
1106 return search(trait_ref);
1115 /// Build the type of all specific fields of a struct or enum variant.
1116 pub(crate) fn field_types_query(
1117 db: &dyn HirDatabase,
1118 variant_id: VariantId,
1119 ) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> {
1120 let var_data = variant_id.variant_data(db.upcast());
1121 let (resolver, def): (_, GenericDefId) = match variant_id {
1122 VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()),
1123 VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()),
1124 VariantId::EnumVariantId(it) => (it.parent.resolver(db.upcast()), it.parent.into()),
1126 let generics = generics(db.upcast(), def);
1127 let mut res = ArenaMap::default();
1129 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1130 for (field_id, field_data) in var_data.fields().iter() {
1131 res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref)))
1136 /// This query exists only to be used when resolving short-hand associated types
1139 /// See the analogous query in rustc and its comment:
1140 /// <https://github.com/rust-lang/rust/blob/9150f844e2624eb013ec78ca08c1d416e6644026/src/librustc_typeck/astconv.rs#L46>
1141 /// This is a query mostly to handle cycles somewhat gracefully; e.g. the
1142 /// following bounds are disallowed: `T: Foo<U::Item>, U: Foo<T::Item>`, but
1143 /// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
1144 pub(crate) fn generic_predicates_for_param_query(
1145 db: &dyn HirDatabase,
1147 param_id: TypeOrConstParamId,
1148 assoc_name: Option<Name>,
1149 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1150 let resolver = def.resolver(db.upcast());
1152 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1153 let generics = generics(db.upcast(), def);
1154 let mut predicates: Vec<_> = resolver
1155 .where_predicates_in_scope()
1156 // we have to filter out all other predicates *first*, before attempting to lower them
1157 .filter(|pred| match pred {
1158 WherePredicate::ForLifetime { target, bound, .. }
1159 | WherePredicate::TypeBound { target, bound, .. } => {
1161 WherePredicateTypeTarget::TypeRef(type_ref) => {
1162 if ctx.lower_ty_only_param(type_ref) != Some(param_id) {
1166 WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
1167 if *local_id != param_id.local_id {
1174 TypeBound::ForLifetime(_, path) | TypeBound::Path(path, _) => {
1175 // Only lower the bound if the trait could possibly define the associated
1176 // type we're looking for.
1178 let assoc_name = match &assoc_name {
1180 None => return true,
1182 let tr = match resolver
1183 .resolve_path_in_type_ns_fully(db.upcast(), path.mod_path())
1185 Some(TypeNs::TraitId(tr)) => tr,
1189 all_super_traits(db.upcast(), tr).iter().any(|tr| {
1190 db.trait_data(*tr).items.iter().any(|(name, item)| {
1191 matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name
1195 TypeBound::Lifetime(_) | TypeBound::Error => false,
1198 WherePredicate::Lifetime { .. } => false,
1201 ctx.lower_where_predicate(pred, true).map(|p| make_binders(db, &generics, p))
1205 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1206 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1207 let implicitly_sized_predicates =
1208 implicitly_sized_clauses(db, param_id.parent, &explicitly_unsized_tys, &subst, &resolver)
1209 .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1210 predicates.extend(implicitly_sized_predicates);
1214 pub(crate) fn generic_predicates_for_param_recover(
1215 _db: &dyn HirDatabase,
1217 _def: &GenericDefId,
1218 _param_id: &TypeOrConstParamId,
1219 _assoc_name: &Option<Name>,
1220 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1224 pub(crate) fn trait_environment_query(
1225 db: &dyn HirDatabase,
1227 ) -> Arc<TraitEnvironment> {
1228 let resolver = def.resolver(db.upcast());
1230 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Placeholder);
1231 let mut traits_in_scope = Vec::new();
1232 let mut clauses = Vec::new();
1233 for pred in resolver.where_predicates_in_scope() {
1234 for pred in ctx.lower_where_predicate(pred, false) {
1235 if let WhereClause::Implemented(tr) = &pred.skip_binders() {
1236 traits_in_scope.push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id()));
1238 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1239 clauses.push(program_clause.into_from_env_clause(Interner));
1243 let container: Option<ItemContainerId> = match def {
1244 // FIXME: is there a function for this?
1245 GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
1246 GenericDefId::AdtId(_) => None,
1247 GenericDefId::TraitId(_) => None,
1248 GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container),
1249 GenericDefId::ImplId(_) => None,
1250 GenericDefId::EnumVariantId(_) => None,
1251 GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container),
1253 if let Some(ItemContainerId::TraitId(trait_id)) = container {
1254 // add `Self: Trait<T1, T2, ...>` to the environment in trait
1255 // function default implementations (and speculative code
1256 // inside consts or type aliases)
1257 cov_mark::hit!(trait_self_implements_self);
1258 let substs = TyBuilder::placeholder_subst(db, trait_id);
1259 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
1260 let pred = WhereClause::Implemented(trait_ref);
1261 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1262 clauses.push(program_clause.into_from_env_clause(Interner));
1265 let subst = generics(db.upcast(), def).placeholder_subst(db);
1266 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1267 let implicitly_sized_clauses =
1268 implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver).map(|pred| {
1269 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1270 program_clause.into_from_env_clause(Interner)
1272 clauses.extend(implicitly_sized_clauses);
1274 let krate = def.module(db.upcast()).krate();
1276 let env = chalk_ir::Environment::new(Interner).add_clauses(Interner, clauses);
1278 Arc::new(TraitEnvironment { krate, traits_from_clauses: traits_in_scope, env })
1281 /// Resolve the where clause(s) of an item with generics.
1282 pub(crate) fn generic_predicates_query(
1283 db: &dyn HirDatabase,
1285 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1286 let resolver = def.resolver(db.upcast());
1288 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1289 let generics = generics(db.upcast(), def);
1291 let mut predicates = resolver
1292 .where_predicates_in_scope()
1294 ctx.lower_where_predicate(pred, false).map(|p| make_binders(db, &generics, p))
1296 .collect::<Vec<_>>();
1298 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1299 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1300 let implicitly_sized_predicates =
1301 implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver)
1302 .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1303 predicates.extend(implicitly_sized_predicates);
1307 /// Generate implicit `: Sized` predicates for all generics that has no `?Sized` bound.
1308 /// Exception is Self of a trait def.
1309 fn implicitly_sized_clauses<'a>(
1310 db: &dyn HirDatabase,
1312 explicitly_unsized_tys: &'a FxHashSet<Ty>,
1313 substitution: &'a Substitution,
1314 resolver: &Resolver,
1315 ) -> impl Iterator<Item = WhereClause> + 'a {
1316 let is_trait_def = matches!(def, GenericDefId::TraitId(..));
1317 let generic_args = &substitution.as_slice(Interner)[is_trait_def as usize..];
1318 let sized_trait = db
1319 .lang_item(resolver.krate(), SmolStr::new_inline("sized"))
1320 .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1322 sized_trait.into_iter().flat_map(move |sized_trait| {
1323 let implicitly_sized_tys = generic_args
1325 .filter_map(|generic_arg| generic_arg.ty(Interner))
1326 .filter(move |&self_ty| !explicitly_unsized_tys.contains(self_ty));
1327 implicitly_sized_tys.map(move |self_ty| {
1328 WhereClause::Implemented(TraitRef {
1329 trait_id: sized_trait,
1330 substitution: Substitution::from1(Interner, self_ty.clone()),
1336 /// Resolve the default type params from generics
1337 pub(crate) fn generic_defaults_query(
1338 db: &dyn HirDatabase,
1340 ) -> Arc<[Binders<chalk_ir::GenericArg<Interner>>]> {
1341 let resolver = def.resolver(db.upcast());
1343 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1344 let generic_params = generics(db.upcast(), def);
1346 let defaults = generic_params
1349 .map(|(idx, (id, p))| {
1351 TypeOrConstParamData::TypeParamData(p) => p,
1352 TypeOrConstParamData::ConstParamData(_) => {
1353 // FIXME: implement const generic defaults
1354 let val = unknown_const_as_generic(
1355 db.const_param_ty(ConstParamId::from_unchecked(id)),
1357 return crate::make_binders_with_count(db, idx, &generic_params, val);
1361 p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
1363 // Each default can only refer to previous parameters.
1364 // type variable default referring to parameter coming
1365 // after it. This is forbidden (FIXME: report
1367 ty = fallback_bound_vars(ty, idx);
1368 let val = GenericArgData::Ty(ty).intern(Interner);
1369 crate::make_binders_with_count(db, idx, &generic_params, val)
1376 pub(crate) fn generic_defaults_recover(
1377 db: &dyn HirDatabase,
1380 ) -> Arc<[Binders<crate::GenericArg>]> {
1381 let generic_params = generics(db.upcast(), *def);
1382 // FIXME: this code is not covered in tests.
1383 // we still need one default per parameter
1384 let defaults = generic_params
1387 .map(|(count, id)| {
1388 let val = match id {
1389 itertools::Either::Left(_) => {
1390 GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1392 itertools::Either::Right(id) => unknown_const_as_generic(db.const_param_ty(id)),
1394 crate::make_binders_with_count(db, count, &generic_params, val)
1401 fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1402 let data = db.function_data(def);
1403 let resolver = def.resolver(db.upcast());
1404 let ctx_params = TyLoweringContext::new(db, &resolver)
1405 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
1406 .with_type_param_mode(ParamLoweringMode::Variable);
1407 let params = data.params.iter().map(|(_, tr)| ctx_params.lower_ty(tr)).collect::<Vec<_>>();
1408 let ctx_ret = TyLoweringContext::new(db, &resolver)
1409 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1410 .with_type_param_mode(ParamLoweringMode::Variable);
1411 let ret = ctx_ret.lower_ty(&data.ret_type);
1412 let generics = generics(db.upcast(), def.into());
1413 let sig = CallableSig::from_params_and_return(params, ret, data.is_varargs());
1414 make_binders(db, &generics, sig)
1417 /// Build the declared type of a function. This should not need to look at the
1419 fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1420 let generics = generics(db.upcast(), def.into());
1421 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1425 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(Interner),
1429 /// Build the declared type of a const.
1430 fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
1431 let data = db.const_data(def);
1432 let generics = generics(db.upcast(), def.into());
1433 let resolver = def.resolver(db.upcast());
1435 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1437 make_binders(db, &generics, ctx.lower_ty(&data.type_ref))
1440 /// Build the declared type of a static.
1441 fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
1442 let data = db.static_data(def);
1443 let resolver = def.resolver(db.upcast());
1444 let ctx = TyLoweringContext::new(db, &resolver);
1446 Binders::empty(Interner, ctx.lower_ty(&data.type_ref))
1449 fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
1450 let struct_data = db.struct_data(def);
1451 let fields = struct_data.variant_data.fields();
1452 let resolver = def.resolver(db.upcast());
1454 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1455 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1456 let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
1457 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1460 /// Build the type of a tuple struct constructor.
1461 fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<Ty> {
1462 let struct_data = db.struct_data(def);
1463 if let StructKind::Unit = struct_data.variant_data.kind() {
1464 return type_for_adt(db, def.into());
1466 let generics = generics(db.upcast(), def.into());
1467 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1471 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
1475 fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
1476 let enum_data = db.enum_data(def.parent);
1477 let var_data = &enum_data.variants[def.local_id];
1478 let fields = var_data.variant_data.fields();
1479 let resolver = def.parent.resolver(db.upcast());
1481 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1482 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1483 let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
1484 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1487 /// Build the type of a tuple enum variant constructor.
1488 fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> Binders<Ty> {
1489 let enum_data = db.enum_data(def.parent);
1490 let var_data = &enum_data.variants[def.local_id].variant_data;
1491 if let StructKind::Unit = var_data.kind() {
1492 return type_for_adt(db, def.parent.into());
1494 let generics = generics(db.upcast(), def.parent.into());
1495 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1499 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(Interner),
1503 fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1504 let generics = generics(db.upcast(), adt.into());
1505 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1506 let ty = TyKind::Adt(crate::AdtId(adt), subst).intern(Interner);
1507 make_binders(db, &generics, ty)
1510 fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1511 let generics = generics(db.upcast(), t.into());
1512 let resolver = t.resolver(db.upcast());
1514 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1515 if db.type_alias_data(t).is_extern {
1516 Binders::empty(Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner))
1518 let type_ref = &db.type_alias_data(t).type_ref;
1519 let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
1520 make_binders(db, &generics, inner)
1524 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1525 pub enum CallableDefId {
1526 FunctionId(FunctionId),
1528 EnumVariantId(EnumVariantId),
1530 impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
1532 impl CallableDefId {
1533 pub fn krate(self, db: &dyn HirDatabase) -> CrateId {
1534 let db = db.upcast();
1536 CallableDefId::FunctionId(f) => f.lookup(db).module(db),
1537 CallableDefId::StructId(s) => s.lookup(db).container,
1538 CallableDefId::EnumVariantId(e) => e.parent.lookup(db).container,
1544 impl From<CallableDefId> for GenericDefId {
1545 fn from(def: CallableDefId) -> GenericDefId {
1547 CallableDefId::FunctionId(f) => f.into(),
1548 CallableDefId::StructId(s) => s.into(),
1549 CallableDefId::EnumVariantId(e) => e.into(),
1554 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1556 BuiltinType(BuiltinType),
1558 TypeAliasId(TypeAliasId),
1560 impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
1562 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1563 pub enum ValueTyDefId {
1564 FunctionId(FunctionId),
1567 EnumVariantId(EnumVariantId),
1571 impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
1573 /// Build the declared type of an item. This depends on the namespace; e.g. for
1574 /// `struct Foo(usize)`, we have two types: The type of the struct itself, and
1575 /// the constructor function `(usize) -> Foo` which lives in the values
1577 pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
1579 TyDefId::BuiltinType(it) => Binders::empty(Interner, TyBuilder::builtin(it)),
1580 TyDefId::AdtId(it) => type_for_adt(db, it),
1581 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
1585 pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> {
1586 let generics = match *def {
1587 TyDefId::BuiltinType(_) => return Binders::empty(Interner, TyKind::Error.intern(Interner)),
1588 TyDefId::AdtId(it) => generics(db.upcast(), it.into()),
1589 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()),
1591 make_binders(db, &generics, TyKind::Error.intern(Interner))
1594 pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
1596 ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
1597 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
1598 ValueTyDefId::UnionId(it) => type_for_adt(db, it.into()),
1599 ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
1600 ValueTyDefId::ConstId(it) => type_for_const(db, it),
1601 ValueTyDefId::StaticId(it) => type_for_static(db, it),
1605 pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> {
1606 let impl_loc = impl_id.lookup(db.upcast());
1607 let impl_data = db.impl_data(impl_id);
1608 let resolver = impl_id.resolver(db.upcast());
1609 let _cx = stdx::panic_context::enter(format!(
1610 "impl_self_ty_query({:?} -> {:?} -> {:?})",
1611 impl_id, impl_loc, impl_data
1613 let generics = generics(db.upcast(), impl_id.into());
1615 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1616 make_binders(db, &generics, ctx.lower_ty(&impl_data.self_ty))
1619 // returns None if def is a type arg
1620 pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
1621 let parent_data = db.generic_params(def.parent());
1622 let data = &parent_data.type_or_consts[def.local_id()];
1623 let resolver = def.parent().resolver(db.upcast());
1624 let ctx = TyLoweringContext::new(db, &resolver);
1626 TypeOrConstParamData::TypeParamData(_) => {
1628 Ty::new(Interner, TyKind::Error)
1630 TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(&d.ty),
1634 pub(crate) fn impl_self_ty_recover(
1635 db: &dyn HirDatabase,
1639 let generics = generics(db.upcast(), (*impl_id).into());
1640 make_binders(db, &generics, TyKind::Error.intern(Interner))
1643 pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
1644 let impl_loc = impl_id.lookup(db.upcast());
1645 let impl_data = db.impl_data(impl_id);
1646 let resolver = impl_id.resolver(db.upcast());
1647 let _cx = stdx::panic_context::enter(format!(
1648 "impl_trait_query({:?} -> {:?} -> {:?})",
1649 impl_id, impl_loc, impl_data
1652 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1653 let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
1654 let target_trait = impl_data.target_trait.as_ref()?;
1655 Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
1658 pub(crate) fn return_type_impl_traits(
1659 db: &dyn HirDatabase,
1660 def: hir_def::FunctionId,
1661 ) -> Option<Arc<Binders<ReturnTypeImplTraits>>> {
1662 // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
1663 let data = db.function_data(def);
1664 let resolver = def.resolver(db.upcast());
1665 let ctx_ret = TyLoweringContext::new(db, &resolver)
1666 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1667 .with_type_param_mode(ParamLoweringMode::Variable);
1668 let _ret = (&ctx_ret).lower_ty(&data.ret_type);
1669 let generics = generics(db.upcast(), def.into());
1670 let return_type_impl_traits =
1671 ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() };
1672 if return_type_impl_traits.impl_traits.is_empty() {
1675 Some(Arc::new(make_binders(db, &generics, return_type_impl_traits)))
1679 pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mutability {
1681 hir_def::type_ref::Mutability::Shared => Mutability::Not,
1682 hir_def::type_ref::Mutability::Mut => Mutability::Mut,
1686 /// Checks if the provided generic arg matches its expected kind, then lower them via
1687 /// provided closures. Use unknown if there was kind mismatch.
1689 /// Returns `Some` of the lowered generic arg. `None` if the provided arg is a lifetime.
1690 pub(crate) fn generic_arg_to_chalk<'a, T>(
1691 db: &dyn HirDatabase,
1692 kind_id: Either<TypeParamId, ConstParamId>,
1693 arg: &'a GenericArg,
1695 for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a,
1696 for_const: impl FnOnce(&mut T, &ConstScalarOrPath, Ty) -> Const + 'a,
1697 ) -> Option<crate::GenericArg> {
1698 let kind = match kind_id {
1699 Either::Left(_) => ParamKind::Type,
1700 Either::Right(id) => {
1701 let ty = db.const_param_ty(id);
1702 ParamKind::Const(ty)
1705 Some(match (arg, kind) {
1706 (GenericArg::Type(type_ref), ParamKind::Type) => {
1707 let ty = for_type(this, type_ref);
1708 GenericArgData::Ty(ty).intern(Interner)
1710 (GenericArg::Const(c), ParamKind::Const(c_ty)) => {
1711 GenericArgData::Const(for_const(this, c, c_ty)).intern(Interner)
1713 (GenericArg::Const(_), ParamKind::Type) => {
1714 GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1716 (GenericArg::Type(t), ParamKind::Const(c_ty)) => {
1717 // We want to recover simple idents, which parser detects them
1718 // as types. Maybe here is not the best place to do it, but
1720 if let TypeRef::Path(p) = t {
1721 let p = p.mod_path();
1722 if p.kind == PathKind::Plain {
1723 if let [n] = p.segments() {
1724 let c = ConstScalarOrPath::Path(n.clone());
1726 GenericArgData::Const(for_const(this, &c, c_ty)).intern(Interner),
1731 unknown_const_as_generic(c_ty)
1733 (GenericArg::Lifetime(_), _) => return None,
1737 pub(crate) fn const_or_path_to_chalk(
1738 db: &dyn HirDatabase,
1739 resolver: &Resolver,
1741 value: &ConstScalarOrPath,
1742 mode: ParamLoweringMode,
1743 args: impl FnOnce() -> Generics,
1744 debruijn: DebruijnIndex,
1747 ConstScalarOrPath::Scalar(s) => intern_const_scalar_with_type(s.clone(), expected_ty),
1748 ConstScalarOrPath::Path(n) => {
1749 let path = ModPath::from_segments(PathKind::Plain, Some(n.clone()));
1750 path_to_const(db, resolver, &path, mode, args, debruijn)
1751 .unwrap_or_else(|| unknown_const(expected_ty))
1756 /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
1757 /// num_vars_to_keep) by `TyKind::Unknown`.
1758 fn fallback_bound_vars<T: TypeFoldable<Interner> + HasInterner<Interner = Interner>>(
1760 num_vars_to_keep: usize,
1762 crate::fold_free_vars(
1765 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1766 TyKind::Error.intern(Interner)
1768 bound.shifted_in_from(binders).to_ty(Interner)
1771 |ty, bound, binders| {
1772 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1773 unknown_const(ty.clone())
1775 bound.shifted_in_from(binders).to_const(Interner, ty)