1 //! Methods for lowering the HIR to types. There are two main cases here:
3 //! - Lowering a type reference like `&usize` or `Option<foo::bar::Baz>` to a
4 //! type: The entry point for this is `Ty::from_hir`.
5 //! - Building the type for an item: This happens through the `type_for_def` query.
7 //! This usually involves resolving names, collecting generic arguments etc.
16 cast::Cast, fold::Shift, fold::TypeFoldable, interner::HasInterner, Mutability, Safety,
21 body::{Expander, LowerCtx},
22 builtin_type::BuiltinType,
24 TypeOrConstParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
28 path::{GenericArg, ModPath, Path, PathKind, PathSegment, PathSegments},
29 resolver::{HasResolver, Resolver, TypeNs},
31 ConstScalarOrPath, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef,
33 AdtId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId,
34 HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
35 TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, VariantId,
37 use hir_expand::{name::Name, ExpandResult};
38 use itertools::Either;
39 use la_arena::ArenaMap;
40 use rustc_hash::FxHashSet;
41 use smallvec::SmallVec;
42 use stdx::{impl_from, never};
43 use syntax::{ast, SmolStr};
47 consteval::{intern_const_scalar, path_to_const, unknown_const, unknown_const_as_generic},
51 static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
53 utils::{all_super_trait_refs, associated_type_by_name_including_super_traits, generics},
54 AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, DebruijnIndex, DynTy, FnPointer,
55 FnSig, FnSubst, GenericArgData, ImplTraitId, Interner, ParamKind, PolyFnSig, ProjectionTy,
56 QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits,
57 Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
61 pub struct TyLoweringContext<'a> {
62 pub db: &'a dyn HirDatabase,
63 pub resolver: &'a Resolver,
64 in_binders: DebruijnIndex,
65 /// Note: Conceptually, it's thinkable that we could be in a location where
66 /// some type params should be represented as placeholders, and others
67 /// should be converted to variables. I think in practice, this isn't
68 /// possible currently, so this should be fine for now.
69 pub type_param_mode: ParamLoweringMode,
70 pub impl_trait_mode: ImplTraitLoweringMode,
71 impl_trait_counter: Cell<u16>,
72 /// When turning `impl Trait` into opaque types, we have to collect the
73 /// bounds at the same time to get the IDs correct (without becoming too
74 /// complicated). I don't like using interior mutability (as for the
75 /// counter), but I've tried and failed to make the lifetimes work for
76 /// passing around a `&mut TyLoweringContext`. The core problem is that
77 /// we're grouping the mutable data (the counter and this field) together
78 /// with the immutable context (the references to the DB and resolver).
79 /// Splitting this up would be a possible fix.
80 opaque_type_data: RefCell<Vec<ReturnTypeImplTrait>>,
81 expander: RefCell<Option<Expander>>,
82 /// Tracks types with explicit `?Sized` bounds.
83 pub(crate) unsized_types: RefCell<FxHashSet<Ty>>,
86 impl<'a> TyLoweringContext<'a> {
87 pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver) -> Self {
88 let impl_trait_counter = Cell::new(0);
89 let impl_trait_mode = ImplTraitLoweringMode::Disallowed;
90 let type_param_mode = ParamLoweringMode::Placeholder;
91 let in_binders = DebruijnIndex::INNERMOST;
92 let opaque_type_data = RefCell::new(Vec::new());
101 expander: RefCell::new(None),
102 unsized_types: RefCell::default(),
106 pub fn with_debruijn<T>(
108 debruijn: DebruijnIndex,
109 f: impl FnOnce(&TyLoweringContext<'_>) -> T,
111 let opaque_ty_data_vec = self.opaque_type_data.take();
112 let expander = self.expander.take();
113 let unsized_types = self.unsized_types.take();
115 in_binders: debruijn,
116 impl_trait_counter: Cell::new(self.impl_trait_counter.get()),
117 opaque_type_data: RefCell::new(opaque_ty_data_vec),
118 expander: RefCell::new(expander),
119 unsized_types: RefCell::new(unsized_types),
122 let result = f(&new_ctx);
123 self.impl_trait_counter.set(new_ctx.impl_trait_counter.get());
124 self.opaque_type_data.replace(new_ctx.opaque_type_data.into_inner());
125 self.expander.replace(new_ctx.expander.into_inner());
126 self.unsized_types.replace(new_ctx.unsized_types.into_inner());
130 pub fn with_shifted_in<T>(
132 debruijn: DebruijnIndex,
133 f: impl FnOnce(&TyLoweringContext<'_>) -> T,
135 self.with_debruijn(self.in_binders.shifted_in_from(debruijn), f)
138 pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
139 Self { impl_trait_mode, ..self }
142 pub fn with_type_param_mode(self, type_param_mode: ParamLoweringMode) -> Self {
143 Self { type_param_mode, ..self }
147 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
148 pub enum ImplTraitLoweringMode {
149 /// `impl Trait` gets lowered into an opaque type that doesn't unify with
150 /// anything except itself. This is used in places where values flow 'out',
151 /// i.e. for arguments of the function we're currently checking, and return
152 /// types of functions we're calling.
154 /// `impl Trait` gets lowered into a type variable. Used for argument
155 /// position impl Trait when inside the respective function, since it allows
156 /// us to support that without Chalk.
158 /// `impl Trait` gets lowered into a variable that can unify with some
159 /// type. This is used in places where values flow 'in', i.e. for arguments
160 /// of functions we're calling, and the return type of the function we're
161 /// currently checking.
163 /// `impl Trait` is disallowed and will be an error.
167 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
168 pub enum ParamLoweringMode {
173 impl<'a> TyLoweringContext<'a> {
174 pub fn lower_ty(&self, type_ref: &TypeRef) -> Ty {
175 self.lower_ty_ext(type_ref).0
178 fn generics(&self) -> Generics {
183 .expect("there should be generics if there's a generic param"),
187 pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
189 let ty = match type_ref {
190 TypeRef::Never => TyKind::Never.intern(Interner),
191 TypeRef::Tuple(inner) => {
192 let inner_tys = inner.iter().map(|tr| self.lower_ty(tr));
193 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(Interner, inner_tys))
196 TypeRef::Path(path) => {
197 let (ty, res_) = self.lower_path(path);
201 TypeRef::RawPtr(inner, mutability) => {
202 let inner_ty = self.lower_ty(inner);
203 TyKind::Raw(lower_to_chalk_mutability(*mutability), inner_ty).intern(Interner)
205 TypeRef::Array(inner, len) => {
206 let inner_ty = self.lower_ty(inner);
207 let const_len = const_or_path_to_chalk(
212 self.type_param_mode,
217 TyKind::Array(inner_ty, const_len).intern(Interner)
219 TypeRef::Slice(inner) => {
220 let inner_ty = self.lower_ty(inner);
221 TyKind::Slice(inner_ty).intern(Interner)
223 TypeRef::Reference(inner, _, mutability) => {
224 let inner_ty = self.lower_ty(inner);
225 let lifetime = static_lifetime();
226 TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty)
229 TypeRef::Placeholder => TyKind::Error.intern(Interner),
230 TypeRef::Fn(params, is_varargs) => {
231 let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
232 Substitution::from_iter(Interner, params.iter().map(|(_, tr)| ctx.lower_ty(tr)))
234 TyKind::Function(FnPointer {
235 num_binders: 0, // FIXME lower `for<'a> fn()` correctly
236 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
237 substitution: FnSubst(substs),
241 TypeRef::DynTrait(bounds) => 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 (expander, recursion_start) = {
334 let mut expander = self.expander.borrow_mut();
335 if expander.is_some() {
336 (Some(expander), false)
338 *expander = Some(Expander::new(
341 self.resolver.module(),
343 (Some(expander), true)
346 let ty = if let Some(mut expander) = expander {
347 let expander_mut = expander.as_mut().unwrap();
348 let macro_call = macro_call.to_node(self.db.upcast());
349 match expander_mut.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
350 Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
352 LowerCtx::new(self.db.upcast(), expander_mut.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);
371 *self.expander.borrow_mut() = None;
373 ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
375 TypeRef::Error => TyKind::Error.intern(Interner),
380 /// This is only for `generic_predicates_for_param`, where we can't just
381 /// lower the self types of the predicates since that could lead to cycles.
382 /// So we just check here if the `type_ref` resolves to a generic param, and which.
383 fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeOrConstParamId> {
384 let path = match type_ref {
385 TypeRef::Path(path) => path,
388 if path.type_anchor().is_some() {
391 if path.segments().len() > 1 {
395 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
396 Some((it, None)) => it,
400 TypeNs::GenericParam(param_id) => Some(param_id.into()),
405 pub(crate) fn lower_ty_relative_path(
408 // We need the original resolution to lower `Self::AssocTy` correctly
410 remaining_segments: PathSegments<'_>,
411 ) -> (Ty, Option<TypeNs>) {
412 match remaining_segments.len() {
415 // resolve unselected assoc types
416 let segment = remaining_segments.first().unwrap();
417 (self.select_associated_type(res, segment), None)
420 // FIXME report error (ambiguous associated type)
421 (TyKind::Error.intern(Interner), None)
426 pub(crate) fn lower_partly_resolved_path(
429 resolved_segment: PathSegment<'_>,
430 remaining_segments: PathSegments<'_>,
432 ) -> (Ty, Option<TypeNs>) {
433 let ty = match resolution {
434 TypeNs::TraitId(trait_) => {
435 let ty = match remaining_segments.len() {
438 self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None);
439 let segment = remaining_segments.first().unwrap();
442 .trait_data(trait_ref.hir_trait_id())
443 .associated_type_by_name(segment.name);
445 Some(associated_ty) => {
446 // FIXME handle type parameters on the segment
447 TyKind::Alias(AliasTy::Projection(ProjectionTy {
448 associated_ty_id: to_assoc_type_id(associated_ty),
449 substitution: trait_ref.substitution,
454 // FIXME: report error (associated type not found)
455 TyKind::Error.intern(Interner)
460 // Trait object type without dyn; this should be handled in upstream. See
462 stdx::never!("unexpected fully resolved trait path");
463 TyKind::Error.intern(Interner)
466 // FIXME report error (ambiguous associated type)
467 TyKind::Error.intern(Interner)
472 TypeNs::GenericParam(param_id) => {
473 let generics = generics(
475 self.resolver.generic_def().expect("generics in scope"),
477 match self.type_param_mode {
478 ParamLoweringMode::Placeholder => {
479 TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into()))
481 ParamLoweringMode::Variable => {
482 let idx = generics.param_idx(param_id.into()).expect("matching generics");
483 TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
488 TypeNs::SelfType(impl_id) => {
489 let generics = generics(self.db.upcast(), impl_id.into());
490 let substs = match self.type_param_mode {
491 ParamLoweringMode::Placeholder => generics.placeholder_subst(self.db),
492 ParamLoweringMode::Variable => {
493 generics.bound_vars_subst(self.db, self.in_binders)
496 self.db.impl_self_ty(impl_id).substitute(Interner, &substs)
498 TypeNs::AdtSelfType(adt) => {
499 let generics = generics(self.db.upcast(), adt.into());
500 let substs = match self.type_param_mode {
501 ParamLoweringMode::Placeholder => generics.placeholder_subst(self.db),
502 ParamLoweringMode::Variable => {
503 generics.bound_vars_subst(self.db, self.in_binders)
506 self.db.ty(adt.into()).substitute(Interner, &substs)
509 TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args),
510 TypeNs::BuiltinType(it) => {
511 self.lower_path_inner(resolved_segment, it.into(), infer_args)
513 TypeNs::TypeAliasId(it) => {
514 self.lower_path_inner(resolved_segment, it.into(), infer_args)
516 // FIXME: report error
517 TypeNs::EnumVariantId(_) => return (TyKind::Error.intern(Interner), None),
519 self.lower_ty_relative_path(ty, Some(resolution), remaining_segments)
522 pub(crate) fn lower_path(&self, path: &Path) -> (Ty, Option<TypeNs>) {
523 // Resolve the path (in type namespace)
524 if let Some(type_ref) = path.type_anchor() {
525 let (ty, res) = self.lower_ty_ext(type_ref);
526 return self.lower_ty_relative_path(ty, res, path.segments());
529 let (resolution, remaining_index) =
530 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
532 None => return (TyKind::Error.intern(Interner), None),
535 if matches!(resolution, TypeNs::TraitId(_)) && remaining_index.is_none() {
536 // trait object type without dyn
537 let bound = TypeBound::Path(path.clone(), TraitBoundModifier::None);
538 let ty = self.lower_dyn_trait(&[Interned::new(bound)]);
542 let (resolved_segment, remaining_segments) = match remaining_index {
544 path.segments().last().expect("resolved path has at least one element"),
547 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)),
549 self.lower_partly_resolved_path(resolution, resolved_segment, remaining_segments, false)
552 fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
553 let (def, res) = match (self.resolver.generic_def(), res) {
554 (Some(def), Some(res)) => (def, res),
555 _ => return TyKind::Error.intern(Interner),
557 let ty = named_associated_type_shorthand_candidates(
561 Some(segment.name.clone()),
562 move |name, t, associated_ty| {
563 if name == segment.name {
564 let substs = match self.type_param_mode {
565 ParamLoweringMode::Placeholder => {
566 // if we're lowering to placeholders, we have to put
568 let generics = generics(
572 .expect("there should be generics if there's a generic param"),
574 let s = generics.placeholder_subst(self.db);
575 s.apply(t.substitution.clone(), Interner)
577 ParamLoweringMode::Variable => t.substitution.clone(),
579 // We need to shift in the bound vars, since
580 // associated_type_shorthand_candidates does not do that
581 let substs = substs.shifted_in_from(Interner, self.in_binders);
582 // FIXME handle type parameters on the segment
584 TyKind::Alias(AliasTy::Projection(ProjectionTy {
585 associated_ty_id: to_assoc_type_id(associated_ty),
586 substitution: substs,
596 ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
601 segment: PathSegment<'_>,
605 let generic_def = match typeable {
606 TyDefId::BuiltinType(_) => None,
607 TyDefId::AdtId(it) => Some(it.into()),
608 TyDefId::TypeAliasId(it) => Some(it.into()),
610 let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None);
611 self.db.ty(typeable).substitute(Interner, &substs)
614 /// Collect generic arguments from a path into a `Substs`. See also
615 /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
616 pub(super) fn substs_from_path(
619 // Note that we don't call `db.value_type(resolved)` here,
620 // `ValueTyDefId` is just a convenient way to pass generics and
621 // special-case enum variants
622 resolved: ValueTyDefId,
625 let last = path.segments().last().expect("path should have at least one segment");
626 let (segment, generic_def) = match resolved {
627 ValueTyDefId::FunctionId(it) => (last, Some(it.into())),
628 ValueTyDefId::StructId(it) => (last, Some(it.into())),
629 ValueTyDefId::UnionId(it) => (last, Some(it.into())),
630 ValueTyDefId::ConstId(it) => (last, Some(it.into())),
631 ValueTyDefId::StaticId(_) => (last, None),
632 ValueTyDefId::EnumVariantId(var) => {
633 // the generic args for an enum variant may be either specified
634 // on the segment referring to the enum, or on the segment
635 // referring to the variant. So `Option::<T>::None` and
636 // `Option::None::<T>` are both allowed (though the former is
637 // preferred). See also `def_ids_for_path_segments` in rustc.
638 let len = path.segments().len();
639 let penultimate = len.checked_sub(2).and_then(|idx| path.segments().get(idx));
640 let segment = match penultimate {
641 Some(segment) if segment.args_and_bindings.is_some() => segment,
644 (segment, Some(var.parent.into()))
647 self.substs_from_path_segment(segment, generic_def, infer_args, None)
650 fn substs_from_path_segment(
652 segment: PathSegment<'_>,
653 def_generic: Option<GenericDefId>,
655 explicit_self_ty: Option<Ty>,
657 let mut substs = Vec::new();
658 let def_generics = if let Some(def) = def_generic {
659 generics(self.db.upcast(), def)
661 return Substitution::empty(Interner);
663 let (parent_params, self_params, type_params, const_params, impl_trait_params) =
664 def_generics.provenance_split();
666 parent_params + self_params + type_params + const_params + impl_trait_params;
668 let ty_error = GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner);
670 let mut def_generic_iter = def_generics.iter_id();
672 for _ in 0..parent_params {
673 if let Some(eid) = def_generic_iter.next() {
675 Either::Left(_) => substs.push(ty_error.clone()),
676 Either::Right(x) => {
677 substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
683 let fill_self_params = || {
684 for x in explicit_self_ty
686 .map(|x| GenericArgData::Ty(x).intern(Interner))
687 .chain(iter::repeat(ty_error.clone()))
690 if let Some(id) = def_generic_iter.next() {
691 assert!(id.is_left());
696 let mut had_explicit_args = false;
698 if let Some(generic_args) = &segment.args_and_bindings {
699 if !generic_args.has_self_type {
702 let expected_num = if generic_args.has_self_type {
703 self_params + type_params + const_params
705 type_params + const_params
707 let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
708 // if args are provided, it should be all of them, but we can't rely on that
709 for arg in generic_args
712 .filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
716 if let Some(id) = def_generic_iter.next() {
717 if let Some(x) = generic_arg_to_chalk(
722 |_, type_ref| self.lower_ty(type_ref),
724 const_or_path_to_chalk(
729 self.type_param_mode,
735 had_explicit_args = true;
738 // we just filtered them out
739 never!("Unexpected lifetime argument");
747 // handle defaults. In expression or pattern path segments without
748 // explicitly specified type arguments, missing type arguments are inferred
749 // (i.e. defaults aren't used).
750 if !infer_args || had_explicit_args {
751 if let Some(def_generic) = def_generic {
752 let defaults = self.db.generic_defaults(def_generic);
753 assert_eq!(total_len, defaults.len());
755 for default_ty in defaults.iter().skip(substs.len()) {
756 // each default can depend on the previous parameters
757 let substs_so_far = Substitution::from_iter(Interner, substs.clone());
758 if let Some(_id) = def_generic_iter.next() {
759 substs.push(default_ty.clone().substitute(Interner, &substs_so_far));
765 // add placeholders for args that were not provided
766 // FIXME: emit diagnostics in contexts where this is not allowed
767 for eid in def_generic_iter {
769 Either::Left(_) => substs.push(ty_error.clone()),
770 Either::Right(x) => {
771 substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
775 // If this assert fails, it means you pushed into subst but didn't call .next() of def_generic_iter
776 assert_eq!(substs.len(), total_len);
778 Substitution::from_iter(Interner, substs)
781 fn lower_trait_ref_from_path(
784 explicit_self_ty: Option<Ty>,
785 ) -> Option<TraitRef> {
787 match self.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), path.mod_path())? {
788 TypeNs::TraitId(tr) => tr,
791 let segment = path.segments().last().expect("path should have at least one segment");
792 Some(self.lower_trait_ref_from_resolved_path(resolved, segment, explicit_self_ty))
795 pub(crate) fn lower_trait_ref_from_resolved_path(
798 segment: PathSegment<'_>,
799 explicit_self_ty: Option<Ty>,
801 let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
802 TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
807 trait_ref: &HirTraitRef,
808 explicit_self_ty: Option<Ty>,
809 ) -> Option<TraitRef> {
810 self.lower_trait_ref_from_path(&trait_ref.path, explicit_self_ty)
813 fn trait_ref_substs_from_path(
815 segment: PathSegment<'_>,
817 explicit_self_ty: Option<Ty>,
819 self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
822 pub(crate) fn lower_where_predicate(
824 where_predicate: &'a WherePredicate,
825 ignore_bindings: bool,
826 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
827 match where_predicate {
828 WherePredicate::ForLifetime { target, bound, .. }
829 | WherePredicate::TypeBound { target, bound } => {
830 let self_ty = match target {
831 WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
832 WherePredicateTypeTarget::TypeOrConstParam(param_id) => {
833 let generic_def = self.resolver.generic_def().expect("generics in scope");
834 let generics = generics(self.db.upcast(), generic_def);
835 let param_id = hir_def::TypeOrConstParamId {
839 let placeholder = to_placeholder_idx(self.db, param_id);
840 match self.type_param_mode {
841 ParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder),
842 ParamLoweringMode::Variable => {
843 let idx = generics.param_idx(param_id).expect("matching generics");
844 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
850 self.lower_type_bound(bound, self_ty, ignore_bindings)
854 WherePredicate::Lifetime { .. } => vec![].into_iter(),
858 pub(crate) fn lower_type_bound(
860 bound: &'a TypeBound,
862 ignore_bindings: bool,
863 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
864 let mut bindings = None;
865 let trait_ref = match bound {
866 TypeBound::Path(path, TraitBoundModifier::None) => {
867 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
871 // ignore `T: Drop` or `T: Destruct` bounds.
872 // - `T: ~const Drop` has a special meaning in Rust 1.61 that we don't implement.
873 // (So ideally, we'd only ignore `~const Drop` here)
874 // - `Destruct` impls are built-in in 1.62 (current nightlies as of 08-04-2022), so until
875 // the builtin impls are supported by Chalk, we ignore them here.
876 if let Some(lang) = lang_attr(self.db.upcast(), tr.hir_trait_id()) {
877 if lang == "drop" || lang == "destruct" {
883 .map(WhereClause::Implemented)
884 .map(crate::wrap_empty_binders)
886 TypeBound::Path(path, TraitBoundModifier::Maybe) => {
887 let sized_trait = self
889 .lang_item(self.resolver.krate(), SmolStr::new_inline("sized"))
890 .and_then(|lang_item| lang_item.as_trait());
891 // Don't lower associated type bindings as the only possible relaxed trait bound
892 // `?Sized` has no of them.
893 // If we got another trait here ignore the bound completely.
895 .lower_trait_ref_from_path(path, Some(self_ty.clone()))
896 .map(|trait_ref| trait_ref.hir_trait_id());
897 if trait_id == sized_trait {
898 self.unsized_types.borrow_mut().insert(self_ty);
902 TypeBound::ForLifetime(_, path) => {
903 // FIXME Don't silently drop the hrtb lifetimes here
904 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
905 bindings.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
907 TypeBound::Lifetime(_) => None,
908 TypeBound::Error => None,
910 trait_ref.into_iter().chain(
913 .filter(move |_| !ignore_bindings)
914 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)),
918 fn assoc_type_bindings_from_type_bound(
920 bound: &'a TypeBound,
922 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
923 let last_segment = match bound {
924 TypeBound::Path(path, TraitBoundModifier::None) | TypeBound::ForLifetime(_, path) => {
925 path.segments().last()
927 TypeBound::Path(_, TraitBoundModifier::Maybe)
929 | TypeBound::Lifetime(_) => None,
933 .filter_map(|segment| segment.args_and_bindings)
934 .flat_map(|args_and_bindings| &args_and_bindings.bindings)
935 .flat_map(move |binding| {
936 let found = associated_type_by_name_including_super_traits(
941 let (super_trait_ref, associated_ty) = match found {
942 None => return SmallVec::new(),
945 let projection_ty = ProjectionTy {
946 associated_ty_id: to_assoc_type_id(associated_ty),
947 substitution: super_trait_ref.substitution,
949 let mut preds: SmallVec<[_; 1]> = SmallVec::with_capacity(
950 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
952 if let Some(type_ref) = &binding.type_ref {
953 let ty = self.lower_ty(type_ref);
955 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
956 preds.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
958 for bound in &binding.bounds {
959 preds.extend(self.lower_type_bound(
961 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(Interner),
969 fn lower_dyn_trait(&self, bounds: &[Interned<TypeBound>]) -> Ty {
970 let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
971 let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
972 QuantifiedWhereClauses::from_iter(
974 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
977 let bounds = crate::make_single_type_binders(bounds);
978 TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
983 bounds: &[Interned<TypeBound>],
985 ) -> ReturnTypeImplTrait {
986 cov_mark::hit!(lower_rpit);
987 let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
988 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
989 let mut predicates: Vec<_> = bounds
991 .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
994 if !ctx.unsized_types.borrow().contains(&self_ty) {
995 let krate = func.lookup(ctx.db.upcast()).module(ctx.db.upcast()).krate();
996 let sized_trait = ctx
998 .lang_item(krate, SmolStr::new_inline("sized"))
999 .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1000 let sized_clause = sized_trait.map(|trait_id| {
1001 let clause = WhereClause::Implemented(TraitRef {
1003 substitution: Substitution::from1(Interner, self_ty.clone()),
1005 crate::wrap_empty_binders(clause)
1007 predicates.extend(sized_clause.into_iter());
1008 predicates.shrink_to_fit();
1012 ReturnTypeImplTrait { bounds: crate::make_single_type_binders(predicates) }
1016 fn count_impl_traits(type_ref: &TypeRef) -> usize {
1018 type_ref.walk(&mut |type_ref| {
1019 if matches!(type_ref, TypeRef::ImplTrait(_)) {
1026 /// Build the signature of a callable item (function, struct or enum variant).
1027 pub(crate) fn callable_item_sig(db: &dyn HirDatabase, def: CallableDefId) -> PolyFnSig {
1029 CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f),
1030 CallableDefId::StructId(s) => fn_sig_for_struct_constructor(db, s),
1031 CallableDefId::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e),
1035 pub fn associated_type_shorthand_candidates<R>(
1036 db: &dyn HirDatabase,
1039 cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
1041 named_associated_type_shorthand_candidates(db, def, res, None, cb)
1044 fn named_associated_type_shorthand_candidates<R>(
1045 db: &dyn HirDatabase,
1046 // If the type parameter is defined in an impl and we're in a method, there
1047 // might be additional where clauses to consider
1050 assoc_name: Option<Name>,
1051 mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
1053 let mut search = |t| {
1054 for t in all_super_trait_refs(db, t) {
1055 let data = db.trait_data(t.hir_trait_id());
1057 for (name, assoc_id) in &data.items {
1058 if let AssocItemId::TypeAliasId(alias) = assoc_id {
1059 if let Some(result) = cb(name, &t, *alias) {
1060 return Some(result);
1069 TypeNs::SelfType(impl_id) => search(
1070 // we're _in_ the impl -- the binders get added back later. Correct,
1071 // but it would be nice to make this more explicit
1072 db.impl_trait(impl_id)?.into_value_and_skipped_binders().0,
1074 TypeNs::GenericParam(param_id) => {
1075 let predicates = db.generic_predicates_for_param(def, param_id.into(), assoc_name);
1076 let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
1077 // FIXME: how to correctly handle higher-ranked bounds here?
1078 WhereClause::Implemented(tr) => search(
1080 .shifted_out_to(Interner, DebruijnIndex::ONE)
1081 .expect("FIXME unexpected higher-ranked trait bound"),
1085 if let Some(_) = res {
1088 // Handle `Self::Type` referring to own associated type in trait definitions
1089 if let GenericDefId::TraitId(trait_id) = param_id.parent() {
1090 let generics = generics(db.upcast(), trait_id.into());
1091 if generics.params.type_or_consts[param_id.local_id()].is_trait_self() {
1092 let trait_ref = TyBuilder::trait_ref(db, trait_id)
1093 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
1095 return search(trait_ref);
1104 /// Build the type of all specific fields of a struct or enum variant.
1105 pub(crate) fn field_types_query(
1106 db: &dyn HirDatabase,
1107 variant_id: VariantId,
1108 ) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> {
1109 let var_data = variant_id.variant_data(db.upcast());
1110 let (resolver, def): (_, GenericDefId) = match variant_id {
1111 VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()),
1112 VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()),
1113 VariantId::EnumVariantId(it) => (it.parent.resolver(db.upcast()), it.parent.into()),
1115 let generics = generics(db.upcast(), def);
1116 let mut res = ArenaMap::default();
1118 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1119 for (field_id, field_data) in var_data.fields().iter() {
1120 res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref)));
1125 /// This query exists only to be used when resolving short-hand associated types
1128 /// See the analogous query in rustc and its comment:
1129 /// <https://github.com/rust-lang/rust/blob/9150f844e2624eb013ec78ca08c1d416e6644026/src/librustc_typeck/astconv.rs#L46>
1130 /// This is a query mostly to handle cycles somewhat gracefully; e.g. the
1131 /// following bounds are disallowed: `T: Foo<U::Item>, U: Foo<T::Item>`, but
1132 /// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
1133 pub(crate) fn generic_predicates_for_param_query(
1134 db: &dyn HirDatabase,
1136 param_id: TypeOrConstParamId,
1137 assoc_name: Option<Name>,
1138 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1139 let resolver = def.resolver(db.upcast());
1141 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1142 let generics = generics(db.upcast(), def);
1143 let mut predicates: Vec<_> = resolver
1144 .where_predicates_in_scope()
1145 // we have to filter out all other predicates *first*, before attempting to lower them
1146 .filter(|pred| match pred {
1147 WherePredicate::ForLifetime { target, bound, .. }
1148 | WherePredicate::TypeBound { target, bound, .. } => {
1150 WherePredicateTypeTarget::TypeRef(type_ref) => {
1151 if ctx.lower_ty_only_param(type_ref) != Some(param_id) {
1155 &WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
1156 let target_id = TypeOrConstParamId { parent: def, local_id };
1157 if target_id != param_id {
1164 TypeBound::ForLifetime(_, path) | TypeBound::Path(path, _) => {
1165 // Only lower the bound if the trait could possibly define the associated
1166 // type we're looking for.
1168 let assoc_name = match &assoc_name {
1170 None => return true,
1172 let tr = match resolver
1173 .resolve_path_in_type_ns_fully(db.upcast(), path.mod_path())
1175 Some(TypeNs::TraitId(tr)) => tr,
1179 all_super_traits(db.upcast(), tr).iter().any(|tr| {
1180 db.trait_data(*tr).items.iter().any(|(name, item)| {
1181 matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name
1185 TypeBound::Lifetime(_) | TypeBound::Error => false,
1188 WherePredicate::Lifetime { .. } => false,
1191 ctx.lower_where_predicate(pred, true).map(|p| make_binders(db, &generics, p))
1195 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1196 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1197 let implicitly_sized_predicates =
1198 implicitly_sized_clauses(db, param_id.parent, &explicitly_unsized_tys, &subst, &resolver)
1199 .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1200 predicates.extend(implicitly_sized_predicates);
1204 pub(crate) fn generic_predicates_for_param_recover(
1205 _db: &dyn HirDatabase,
1207 _def: &GenericDefId,
1208 _param_id: &TypeOrConstParamId,
1209 _assoc_name: &Option<Name>,
1210 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1214 pub(crate) fn trait_environment_query(
1215 db: &dyn HirDatabase,
1217 ) -> Arc<TraitEnvironment> {
1218 let resolver = def.resolver(db.upcast());
1220 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Placeholder);
1221 let mut traits_in_scope = Vec::new();
1222 let mut clauses = Vec::new();
1223 for pred in resolver.where_predicates_in_scope() {
1224 for pred in ctx.lower_where_predicate(pred, false) {
1225 if let WhereClause::Implemented(tr) = &pred.skip_binders() {
1226 traits_in_scope.push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id()));
1228 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1229 clauses.push(program_clause.into_from_env_clause(Interner));
1233 let container: Option<ItemContainerId> = match def {
1234 // FIXME: is there a function for this?
1235 GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
1236 GenericDefId::AdtId(_) => None,
1237 GenericDefId::TraitId(_) => None,
1238 GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container),
1239 GenericDefId::ImplId(_) => None,
1240 GenericDefId::EnumVariantId(_) => None,
1241 GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container),
1243 if let Some(ItemContainerId::TraitId(trait_id)) = container {
1244 // add `Self: Trait<T1, T2, ...>` to the environment in trait
1245 // function default implementations (and speculative code
1246 // inside consts or type aliases)
1247 cov_mark::hit!(trait_self_implements_self);
1248 let substs = TyBuilder::placeholder_subst(db, trait_id);
1249 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
1250 let pred = WhereClause::Implemented(trait_ref);
1251 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1252 clauses.push(program_clause.into_from_env_clause(Interner));
1255 let subst = generics(db.upcast(), def).placeholder_subst(db);
1256 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1257 let implicitly_sized_clauses =
1258 implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver).map(|pred| {
1259 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1260 program_clause.into_from_env_clause(Interner)
1262 clauses.extend(implicitly_sized_clauses);
1264 let krate = def.module(db.upcast()).krate();
1266 let env = chalk_ir::Environment::new(Interner).add_clauses(Interner, clauses);
1268 Arc::new(TraitEnvironment { krate, traits_from_clauses: traits_in_scope, env })
1271 /// Resolve the where clause(s) of an item with generics.
1272 pub(crate) fn generic_predicates_query(
1273 db: &dyn HirDatabase,
1275 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1276 let resolver = def.resolver(db.upcast());
1278 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1279 let generics = generics(db.upcast(), def);
1281 let mut predicates = resolver
1282 .where_predicates_in_scope()
1284 ctx.lower_where_predicate(pred, false).map(|p| make_binders(db, &generics, p))
1286 .collect::<Vec<_>>();
1288 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1289 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1290 let implicitly_sized_predicates =
1291 implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver)
1292 .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1293 predicates.extend(implicitly_sized_predicates);
1297 /// Generate implicit `: Sized` predicates for all generics that has no `?Sized` bound.
1298 /// Exception is Self of a trait def.
1299 fn implicitly_sized_clauses<'a>(
1300 db: &dyn HirDatabase,
1302 explicitly_unsized_tys: &'a FxHashSet<Ty>,
1303 substitution: &'a Substitution,
1304 resolver: &Resolver,
1305 ) -> impl Iterator<Item = WhereClause> + 'a {
1306 let is_trait_def = matches!(def, GenericDefId::TraitId(..));
1307 let generic_args = &substitution.as_slice(Interner)[is_trait_def as usize..];
1308 let sized_trait = db
1309 .lang_item(resolver.krate(), SmolStr::new_inline("sized"))
1310 .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1312 sized_trait.into_iter().flat_map(move |sized_trait| {
1313 let implicitly_sized_tys = generic_args
1315 .filter_map(|generic_arg| generic_arg.ty(Interner))
1316 .filter(move |&self_ty| !explicitly_unsized_tys.contains(self_ty));
1317 implicitly_sized_tys.map(move |self_ty| {
1318 WhereClause::Implemented(TraitRef {
1319 trait_id: sized_trait,
1320 substitution: Substitution::from1(Interner, self_ty.clone()),
1326 /// Resolve the default type params from generics
1327 pub(crate) fn generic_defaults_query(
1328 db: &dyn HirDatabase,
1330 ) -> Arc<[Binders<chalk_ir::GenericArg<Interner>>]> {
1331 let resolver = def.resolver(db.upcast());
1333 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1334 let generic_params = generics(db.upcast(), def);
1336 let defaults = generic_params
1339 .map(|(idx, (id, p))| {
1341 TypeOrConstParamData::TypeParamData(p) => p,
1342 TypeOrConstParamData::ConstParamData(_) => {
1343 // FIXME: implement const generic defaults
1344 let val = unknown_const_as_generic(
1345 db.const_param_ty(ConstParamId::from_unchecked(id)),
1347 return crate::make_binders_with_count(db, idx, &generic_params, val);
1351 p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
1353 // Each default can only refer to previous parameters.
1354 // type variable default referring to parameter coming
1355 // after it. This is forbidden (FIXME: report
1357 ty = fallback_bound_vars(ty, idx);
1358 let val = GenericArgData::Ty(ty).intern(Interner);
1359 crate::make_binders_with_count(db, idx, &generic_params, val)
1366 pub(crate) fn generic_defaults_recover(
1367 db: &dyn HirDatabase,
1370 ) -> Arc<[Binders<crate::GenericArg>]> {
1371 let generic_params = generics(db.upcast(), *def);
1372 // FIXME: this code is not covered in tests.
1373 // we still need one default per parameter
1374 let defaults = generic_params
1377 .map(|(count, id)| {
1378 let val = match id {
1379 itertools::Either::Left(_) => {
1380 GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1382 itertools::Either::Right(id) => unknown_const_as_generic(db.const_param_ty(id)),
1384 crate::make_binders_with_count(db, count, &generic_params, val)
1391 fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1392 let data = db.function_data(def);
1393 let resolver = def.resolver(db.upcast());
1394 let ctx_params = TyLoweringContext::new(db, &resolver)
1395 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
1396 .with_type_param_mode(ParamLoweringMode::Variable);
1397 let params = data.params.iter().map(|(_, tr)| ctx_params.lower_ty(tr)).collect::<Vec<_>>();
1398 let ctx_ret = TyLoweringContext::new(db, &resolver)
1399 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1400 .with_type_param_mode(ParamLoweringMode::Variable);
1401 let ret = ctx_ret.lower_ty(&data.ret_type);
1402 let generics = generics(db.upcast(), def.into());
1403 let sig = CallableSig::from_params_and_return(params, ret, data.is_varargs());
1404 make_binders(db, &generics, sig)
1407 /// Build the declared type of a function. This should not need to look at the
1409 fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1410 let generics = generics(db.upcast(), def.into());
1411 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1415 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(Interner),
1419 /// Build the declared type of a const.
1420 fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
1421 let data = db.const_data(def);
1422 let generics = generics(db.upcast(), def.into());
1423 let resolver = def.resolver(db.upcast());
1425 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1427 make_binders(db, &generics, ctx.lower_ty(&data.type_ref))
1430 /// Build the declared type of a static.
1431 fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
1432 let data = db.static_data(def);
1433 let resolver = def.resolver(db.upcast());
1434 let ctx = TyLoweringContext::new(db, &resolver);
1436 Binders::empty(Interner, ctx.lower_ty(&data.type_ref))
1439 fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
1440 let struct_data = db.struct_data(def);
1441 let fields = struct_data.variant_data.fields();
1442 let resolver = def.resolver(db.upcast());
1444 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1445 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1446 let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
1447 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1450 /// Build the type of a tuple struct constructor.
1451 fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<Ty> {
1452 let struct_data = db.struct_data(def);
1453 if let StructKind::Unit = struct_data.variant_data.kind() {
1454 return type_for_adt(db, def.into());
1456 let generics = generics(db.upcast(), def.into());
1457 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1461 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
1465 fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
1466 let enum_data = db.enum_data(def.parent);
1467 let var_data = &enum_data.variants[def.local_id];
1468 let fields = var_data.variant_data.fields();
1469 let resolver = def.parent.resolver(db.upcast());
1471 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1472 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1473 let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
1474 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1477 /// Build the type of a tuple enum variant constructor.
1478 fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> Binders<Ty> {
1479 let enum_data = db.enum_data(def.parent);
1480 let var_data = &enum_data.variants[def.local_id].variant_data;
1481 if let StructKind::Unit = var_data.kind() {
1482 return type_for_adt(db, def.parent.into());
1484 let generics = generics(db.upcast(), def.parent.into());
1485 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1489 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(Interner),
1493 fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1494 let generics = generics(db.upcast(), adt.into());
1495 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1496 let ty = TyKind::Adt(crate::AdtId(adt), subst).intern(Interner);
1497 make_binders(db, &generics, ty)
1500 fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1501 let generics = generics(db.upcast(), t.into());
1502 let resolver = t.resolver(db.upcast());
1504 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1505 if db.type_alias_data(t).is_extern {
1506 Binders::empty(Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner))
1508 let type_ref = &db.type_alias_data(t).type_ref;
1509 let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
1510 make_binders(db, &generics, inner)
1514 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1515 pub enum CallableDefId {
1516 FunctionId(FunctionId),
1518 EnumVariantId(EnumVariantId),
1520 impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
1522 impl CallableDefId {
1523 pub fn krate(self, db: &dyn HirDatabase) -> CrateId {
1524 let db = db.upcast();
1526 CallableDefId::FunctionId(f) => f.lookup(db).module(db),
1527 CallableDefId::StructId(s) => s.lookup(db).container,
1528 CallableDefId::EnumVariantId(e) => e.parent.lookup(db).container,
1534 impl From<CallableDefId> for GenericDefId {
1535 fn from(def: CallableDefId) -> GenericDefId {
1537 CallableDefId::FunctionId(f) => f.into(),
1538 CallableDefId::StructId(s) => s.into(),
1539 CallableDefId::EnumVariantId(e) => e.into(),
1544 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1546 BuiltinType(BuiltinType),
1548 TypeAliasId(TypeAliasId),
1550 impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
1552 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1553 pub enum ValueTyDefId {
1554 FunctionId(FunctionId),
1557 EnumVariantId(EnumVariantId),
1561 impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
1563 /// Build the declared type of an item. This depends on the namespace; e.g. for
1564 /// `struct Foo(usize)`, we have two types: The type of the struct itself, and
1565 /// the constructor function `(usize) -> Foo` which lives in the values
1567 pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
1569 TyDefId::BuiltinType(it) => Binders::empty(Interner, TyBuilder::builtin(it)),
1570 TyDefId::AdtId(it) => type_for_adt(db, it),
1571 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
1575 pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> {
1576 let generics = match *def {
1577 TyDefId::BuiltinType(_) => return Binders::empty(Interner, TyKind::Error.intern(Interner)),
1578 TyDefId::AdtId(it) => generics(db.upcast(), it.into()),
1579 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()),
1581 make_binders(db, &generics, TyKind::Error.intern(Interner))
1584 pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
1586 ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
1587 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
1588 ValueTyDefId::UnionId(it) => type_for_adt(db, it.into()),
1589 ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
1590 ValueTyDefId::ConstId(it) => type_for_const(db, it),
1591 ValueTyDefId::StaticId(it) => type_for_static(db, it),
1595 pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> {
1596 let impl_loc = impl_id.lookup(db.upcast());
1597 let impl_data = db.impl_data(impl_id);
1598 let resolver = impl_id.resolver(db.upcast());
1599 let _cx = stdx::panic_context::enter(format!(
1600 "impl_self_ty_query({:?} -> {:?} -> {:?})",
1601 impl_id, impl_loc, impl_data
1603 let generics = generics(db.upcast(), impl_id.into());
1605 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1606 make_binders(db, &generics, ctx.lower_ty(&impl_data.self_ty))
1609 // returns None if def is a type arg
1610 pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
1611 let parent_data = db.generic_params(def.parent());
1612 let data = &parent_data.type_or_consts[def.local_id()];
1613 let resolver = def.parent().resolver(db.upcast());
1614 let ctx = TyLoweringContext::new(db, &resolver);
1616 TypeOrConstParamData::TypeParamData(_) => {
1618 Ty::new(Interner, TyKind::Error)
1620 TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(&d.ty),
1624 pub(crate) fn impl_self_ty_recover(
1625 db: &dyn HirDatabase,
1629 let generics = generics(db.upcast(), (*impl_id).into());
1630 make_binders(db, &generics, TyKind::Error.intern(Interner))
1633 pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
1634 let impl_loc = impl_id.lookup(db.upcast());
1635 let impl_data = db.impl_data(impl_id);
1636 let resolver = impl_id.resolver(db.upcast());
1637 let _cx = stdx::panic_context::enter(format!(
1638 "impl_trait_query({:?} -> {:?} -> {:?})",
1639 impl_id, impl_loc, impl_data
1642 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1643 let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
1644 let target_trait = impl_data.target_trait.as_ref()?;
1645 Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
1648 pub(crate) fn return_type_impl_traits(
1649 db: &dyn HirDatabase,
1650 def: hir_def::FunctionId,
1651 ) -> Option<Arc<Binders<ReturnTypeImplTraits>>> {
1652 // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
1653 let data = db.function_data(def);
1654 let resolver = def.resolver(db.upcast());
1655 let ctx_ret = TyLoweringContext::new(db, &resolver)
1656 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1657 .with_type_param_mode(ParamLoweringMode::Variable);
1658 let _ret = (&ctx_ret).lower_ty(&data.ret_type);
1659 let generics = generics(db.upcast(), def.into());
1660 let return_type_impl_traits =
1661 ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() };
1662 if return_type_impl_traits.impl_traits.is_empty() {
1665 Some(Arc::new(make_binders(db, &generics, return_type_impl_traits)))
1669 pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mutability {
1671 hir_def::type_ref::Mutability::Shared => Mutability::Not,
1672 hir_def::type_ref::Mutability::Mut => Mutability::Mut,
1676 /// Checks if the provided generic arg matches its expected kind, then lower them via
1677 /// provided closures. Use unknown if there was kind mismatch.
1679 /// Returns `Some` of the lowered generic arg. `None` if the provided arg is a lifetime.
1680 pub(crate) fn generic_arg_to_chalk<'a, T>(
1681 db: &dyn HirDatabase,
1682 kind_id: Either<TypeParamId, ConstParamId>,
1683 arg: &'a GenericArg,
1685 for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a,
1686 for_const: impl FnOnce(&mut T, &ConstScalarOrPath, Ty) -> Const + 'a,
1687 ) -> Option<crate::GenericArg> {
1688 let kind = match kind_id {
1689 Either::Left(_) => ParamKind::Type,
1690 Either::Right(id) => {
1691 let ty = db.const_param_ty(id);
1692 ParamKind::Const(ty)
1695 Some(match (arg, kind) {
1696 (GenericArg::Type(type_ref), ParamKind::Type) => {
1697 let ty = for_type(this, type_ref);
1698 GenericArgData::Ty(ty).intern(Interner)
1700 (GenericArg::Const(c), ParamKind::Const(c_ty)) => {
1701 GenericArgData::Const(for_const(this, c, c_ty)).intern(Interner)
1703 (GenericArg::Const(_), ParamKind::Type) => {
1704 GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1706 (GenericArg::Type(t), ParamKind::Const(c_ty)) => {
1707 // We want to recover simple idents, which parser detects them
1708 // as types. Maybe here is not the best place to do it, but
1710 if let TypeRef::Path(p) = t {
1711 let p = p.mod_path();
1712 if p.kind == PathKind::Plain {
1713 if let [n] = p.segments() {
1714 let c = ConstScalarOrPath::Path(n.clone());
1716 GenericArgData::Const(for_const(this, &c, c_ty)).intern(Interner),
1721 unknown_const_as_generic(c_ty)
1723 (GenericArg::Lifetime(_), _) => return None,
1727 pub(crate) fn const_or_path_to_chalk(
1728 db: &dyn HirDatabase,
1729 resolver: &Resolver,
1731 value: &ConstScalarOrPath,
1732 mode: ParamLoweringMode,
1733 args: impl FnOnce() -> Generics,
1734 debruijn: DebruijnIndex,
1737 ConstScalarOrPath::Scalar(s) => intern_const_scalar(s.clone(), expected_ty),
1738 ConstScalarOrPath::Path(n) => {
1739 let path = ModPath::from_segments(PathKind::Plain, Some(n.clone()));
1740 path_to_const(db, resolver, &path, mode, args, debruijn)
1741 .unwrap_or_else(|| unknown_const(expected_ty))
1746 /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
1747 /// num_vars_to_keep) by `TyKind::Unknown`.
1748 fn fallback_bound_vars<T: TypeFoldable<Interner> + HasInterner<Interner = Interner>>(
1750 num_vars_to_keep: usize,
1752 crate::fold_free_vars(
1755 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1756 TyKind::Error.intern(Interner)
1758 bound.shifted_in_from(binders).to_ty(Interner)
1761 |ty, bound, binders| {
1762 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1763 unknown_const(ty.clone())
1765 bound.shifted_in_from(binders).to_const(Interner, ty)