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 `TyLoweringContext::lower_ty`.
5 //! - Building the type for an item: This happens through the `ty` query.
7 //! This usually involves resolving names, collecting generic arguments etc.
9 cell::{Cell, RefCell, RefMut},
16 cast::Cast, fold::Shift, fold::TypeFoldable, interner::HasInterner, Mutability, Safety,
21 body::{Expander, LowerCtx},
22 builtin_type::BuiltinType,
24 TypeOrConstParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
28 path::{GenericArg, ModPath, Path, PathKind, PathSegment, PathSegments},
29 resolver::{HasResolver, Resolver, TypeNs},
31 ConstScalarOrPath, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef,
33 AdtId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId,
34 HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
35 TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, VariantId,
37 use hir_expand::{name::Name, ExpandResult};
38 use itertools::Either;
39 use la_arena::ArenaMap;
40 use rustc_hash::FxHashSet;
41 use smallvec::SmallVec;
42 use stdx::{impl_from, never};
43 use syntax::{ast, SmolStr};
47 consteval::{intern_const_scalar, path_to_const, unknown_const, unknown_const_as_generic},
50 mapping::{from_chalk_trait_id, ToChalk},
51 static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
53 utils::{all_super_trait_refs, associated_type_by_name_including_super_traits, generics},
54 AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, DebruijnIndex, DynTy, FnPointer,
55 FnSig, FnSubst, GenericArgData, ImplTraitId, Interner, ParamKind, PolyFnSig, ProjectionTy,
56 QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits,
57 Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
61 pub struct TyLoweringContext<'a> {
62 pub db: &'a dyn HirDatabase,
63 pub resolver: &'a Resolver,
64 in_binders: DebruijnIndex,
65 /// Note: Conceptually, it's thinkable that we could be in a location where
66 /// some type params should be represented as placeholders, and others
67 /// should be converted to variables. I think in practice, this isn't
68 /// possible currently, so this should be fine for now.
69 pub type_param_mode: ParamLoweringMode,
70 pub impl_trait_mode: ImplTraitLoweringMode,
71 impl_trait_counter: Cell<u16>,
72 /// When turning `impl Trait` into opaque types, we have to collect the
73 /// bounds at the same time to get the IDs correct (without becoming too
74 /// complicated). I don't like using interior mutability (as for the
75 /// counter), but I've tried and failed to make the lifetimes work for
76 /// passing around a `&mut TyLoweringContext`. The core problem is that
77 /// we're grouping the mutable data (the counter and this field) together
78 /// with the immutable context (the references to the DB and resolver).
79 /// Splitting this up would be a possible fix.
80 opaque_type_data: RefCell<Vec<ReturnTypeImplTrait>>,
81 expander: RefCell<Option<Expander>>,
82 /// Tracks types with explicit `?Sized` bounds.
83 pub(crate) unsized_types: RefCell<FxHashSet<Ty>>,
86 impl<'a> TyLoweringContext<'a> {
87 pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver) -> Self {
88 let impl_trait_counter = Cell::new(0);
89 let impl_trait_mode = ImplTraitLoweringMode::Disallowed;
90 let type_param_mode = ParamLoweringMode::Placeholder;
91 let in_binders = DebruijnIndex::INNERMOST;
92 let opaque_type_data = RefCell::new(Vec::new());
101 expander: RefCell::new(None),
102 unsized_types: RefCell::default(),
106 pub fn with_debruijn<T>(
108 debruijn: DebruijnIndex,
109 f: impl FnOnce(&TyLoweringContext<'_>) -> T,
111 let opaque_ty_data_vec = self.opaque_type_data.take();
112 let expander = self.expander.take();
113 let unsized_types = self.unsized_types.take();
115 in_binders: debruijn,
116 impl_trait_counter: Cell::new(self.impl_trait_counter.get()),
117 opaque_type_data: RefCell::new(opaque_ty_data_vec),
118 expander: RefCell::new(expander),
119 unsized_types: RefCell::new(unsized_types),
122 let result = f(&new_ctx);
123 self.impl_trait_counter.set(new_ctx.impl_trait_counter.get());
124 self.opaque_type_data.replace(new_ctx.opaque_type_data.into_inner());
125 self.expander.replace(new_ctx.expander.into_inner());
126 self.unsized_types.replace(new_ctx.unsized_types.into_inner());
130 pub fn with_shifted_in<T>(
132 debruijn: DebruijnIndex,
133 f: impl FnOnce(&TyLoweringContext<'_>) -> T,
135 self.with_debruijn(self.in_binders.shifted_in_from(debruijn), f)
138 pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
139 Self { impl_trait_mode, ..self }
142 pub fn with_type_param_mode(self, type_param_mode: ParamLoweringMode) -> Self {
143 Self { type_param_mode, ..self }
147 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
148 pub enum ImplTraitLoweringMode {
149 /// `impl Trait` gets lowered into an opaque type that doesn't unify with
150 /// anything except itself. This is used in places where values flow 'out',
151 /// i.e. for arguments of the function we're currently checking, and return
152 /// types of functions we're calling.
154 /// `impl Trait` gets lowered into a type variable. Used for argument
155 /// position impl Trait when inside the respective function, since it allows
156 /// us to support that without Chalk.
158 /// `impl Trait` gets lowered into a variable that can unify with some
159 /// type. This is used in places where values flow 'in', i.e. for arguments
160 /// of functions we're calling, and the return type of the function we're
161 /// currently checking.
163 /// `impl Trait` is disallowed and will be an error.
167 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
168 pub enum ParamLoweringMode {
173 impl<'a> TyLoweringContext<'a> {
174 pub fn lower_ty(&self, type_ref: &TypeRef) -> Ty {
175 self.lower_ty_ext(type_ref).0
178 fn generics(&self) -> Generics {
183 .expect("there should be generics if there's a generic param"),
187 pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
189 let ty = match type_ref {
190 TypeRef::Never => TyKind::Never.intern(Interner),
191 TypeRef::Tuple(inner) => {
192 let inner_tys = inner.iter().map(|tr| self.lower_ty(tr));
193 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(Interner, inner_tys))
196 TypeRef::Path(path) => {
197 let (ty, res_) = self.lower_path(path);
201 TypeRef::RawPtr(inner, mutability) => {
202 let inner_ty = self.lower_ty(inner);
203 TyKind::Raw(lower_to_chalk_mutability(*mutability), inner_ty).intern(Interner)
205 TypeRef::Array(inner, len) => {
206 let inner_ty = self.lower_ty(inner);
207 let const_len = const_or_path_to_chalk(
212 self.type_param_mode,
217 TyKind::Array(inner_ty, const_len).intern(Interner)
219 TypeRef::Slice(inner) => {
220 let inner_ty = self.lower_ty(inner);
221 TyKind::Slice(inner_ty).intern(Interner)
223 TypeRef::Reference(inner, _, mutability) => {
224 let inner_ty = self.lower_ty(inner);
225 let lifetime = static_lifetime();
226 TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty)
229 TypeRef::Placeholder => TyKind::Error.intern(Interner),
230 TypeRef::Fn(params, is_varargs) => {
231 let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
232 Substitution::from_iter(Interner, params.iter().map(|(_, tr)| ctx.lower_ty(tr)))
234 TyKind::Function(FnPointer {
235 num_binders: 0, // FIXME lower `for<'a> fn()` correctly
236 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
237 substitution: FnSubst(substs),
241 TypeRef::DynTrait(bounds) => self.lower_dyn_trait(bounds),
242 TypeRef::ImplTrait(bounds) => {
243 match self.impl_trait_mode {
244 ImplTraitLoweringMode::Opaque => {
245 let idx = self.impl_trait_counter.get();
246 self.impl_trait_counter.set(idx + 1);
247 let func = match self.resolver.generic_def() {
248 Some(GenericDefId::FunctionId(f)) => f,
249 _ => panic!("opaque impl trait lowering in non-function"),
252 assert!(idx as usize == self.opaque_type_data.borrow().len());
253 // this dance is to make sure the data is in the right
254 // place even if we encounter more opaque types while
255 // lowering the bounds
256 self.opaque_type_data.borrow_mut().push(ReturnTypeImplTrait {
257 bounds: crate::make_single_type_binders(Vec::new()),
259 // We don't want to lower the bounds inside the binders
260 // we're currently in, because they don't end up inside
261 // those binders. E.g. when we have `impl Trait<impl
262 // OtherTrait<T>>`, the `impl OtherTrait<T>` can't refer
263 // to the self parameter from `impl Trait`, and the
264 // bounds aren't actually stored nested within each
265 // other, but separately. So if the `T` refers to a type
266 // parameter of the outer function, it's just one binder
267 // away instead of two.
268 let actual_opaque_type_data = self
269 .with_debruijn(DebruijnIndex::INNERMOST, |ctx| {
270 ctx.lower_impl_trait(bounds, func)
272 self.opaque_type_data.borrow_mut()[idx as usize] = actual_opaque_type_data;
274 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx);
275 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
276 let generics = generics(self.db.upcast(), func.into());
277 let parameters = generics.bound_vars_subst(self.db, self.in_binders);
278 TyKind::OpaqueType(opaque_ty_id, parameters).intern(Interner)
280 ImplTraitLoweringMode::Param => {
281 let idx = self.impl_trait_counter.get();
282 // FIXME we're probably doing something wrong here
283 self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
284 if let Some(def) = self.resolver.generic_def() {
285 let generics = generics(self.db.upcast(), def);
288 .filter(|(_, data)| {
291 TypeOrConstParamData::TypeParamData(data)
292 if data.provenance == TypeParamProvenance::ArgumentImplTrait
296 .map_or(TyKind::Error, |(id, _)| {
297 TyKind::Placeholder(to_placeholder_idx(self.db, id))
299 param.intern(Interner)
301 TyKind::Error.intern(Interner)
304 ImplTraitLoweringMode::Variable => {
305 let idx = self.impl_trait_counter.get();
306 // FIXME we're probably doing something wrong here
307 self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
314 ) = if let Some(def) = self.resolver.generic_def() {
315 let generics = generics(self.db.upcast(), def);
316 generics.provenance_split()
320 TyKind::BoundVar(BoundVar::new(
322 idx as usize + parent_params + self_params + list_params + const_params,
326 ImplTraitLoweringMode::Disallowed => {
327 // FIXME: report error
328 TyKind::Error.intern(Interner)
332 TypeRef::Macro(macro_call) => {
333 let (mut expander, recursion_start) = {
334 match RefMut::filter_map(self.expander.borrow_mut(), Option::as_mut) {
335 // There already is an expander here, this means we are already recursing
336 Ok(expander) => (expander, false),
337 // No expander was created yet, so we are at the start of the expansion recursion
338 // and therefore have to create an expander.
340 RefMut::map(expander, |it| {
341 it.insert(Expander::new(
344 self.resolver.module(),
352 let macro_call = macro_call.to_node(self.db.upcast());
353 match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
354 Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
355 let ctx = LowerCtx::new(self.db.upcast(), expander.current_file_id());
356 let type_ref = TypeRef::from_ast(&ctx, expanded);
359 let ty = self.lower_ty(&type_ref);
365 .exit(self.db.upcast(), mark);
375 // drop the expander, resetting it to pre-recursion state
377 *self.expander.borrow_mut() = None;
379 ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
381 TypeRef::Error => TyKind::Error.intern(Interner),
386 /// This is only for `generic_predicates_for_param`, where we can't just
387 /// lower the self types of the predicates since that could lead to cycles.
388 /// So we just check here if the `type_ref` resolves to a generic param, and which.
389 fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeOrConstParamId> {
390 let path = match type_ref {
391 TypeRef::Path(path) => path,
394 if path.type_anchor().is_some() {
397 if path.segments().len() > 1 {
401 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
402 Some((it, None)) => it,
406 TypeNs::GenericParam(param_id) => Some(param_id.into()),
411 pub(crate) fn lower_ty_relative_path(
414 // We need the original resolution to lower `Self::AssocTy` correctly
416 remaining_segments: PathSegments<'_>,
417 ) -> (Ty, Option<TypeNs>) {
418 match remaining_segments.len() {
421 // resolve unselected assoc types
422 let segment = remaining_segments.first().unwrap();
423 (self.select_associated_type(res, segment), None)
426 // FIXME report error (ambiguous associated type)
427 (TyKind::Error.intern(Interner), None)
432 pub(crate) fn lower_partly_resolved_path(
435 resolved_segment: PathSegment<'_>,
436 remaining_segments: PathSegments<'_>,
438 ) -> (Ty, Option<TypeNs>) {
439 let ty = match resolution {
440 TypeNs::TraitId(trait_) => {
441 let ty = match remaining_segments.len() {
444 self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None);
445 let segment = remaining_segments.first().unwrap();
448 .trait_data(trait_ref.hir_trait_id())
449 .associated_type_by_name(segment.name);
451 Some(associated_ty) => {
452 // FIXME handle type parameters on the segment
453 TyKind::Alias(AliasTy::Projection(ProjectionTy {
454 associated_ty_id: to_assoc_type_id(associated_ty),
455 substitution: trait_ref.substitution,
460 // FIXME: report error (associated type not found)
461 TyKind::Error.intern(Interner)
466 // Trait object type without dyn; this should be handled in upstream. See
468 stdx::never!("unexpected fully resolved trait path");
469 TyKind::Error.intern(Interner)
472 // FIXME report error (ambiguous associated type)
473 TyKind::Error.intern(Interner)
478 TypeNs::GenericParam(param_id) => {
479 let generics = generics(
481 self.resolver.generic_def().expect("generics in scope"),
483 match self.type_param_mode {
484 ParamLoweringMode::Placeholder => {
485 TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into()))
487 ParamLoweringMode::Variable => {
488 let idx = match generics.param_idx(param_id.into()) {
490 never!("no matching generics");
491 return (TyKind::Error.intern(Interner), None);
496 TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
501 TypeNs::SelfType(impl_id) => {
502 let generics = generics(self.db.upcast(), impl_id.into());
503 let substs = match self.type_param_mode {
504 ParamLoweringMode::Placeholder => generics.placeholder_subst(self.db),
505 ParamLoweringMode::Variable => {
506 generics.bound_vars_subst(self.db, self.in_binders)
509 self.db.impl_self_ty(impl_id).substitute(Interner, &substs)
511 TypeNs::AdtSelfType(adt) => {
512 let generics = generics(self.db.upcast(), adt.into());
513 let substs = match self.type_param_mode {
514 ParamLoweringMode::Placeholder => generics.placeholder_subst(self.db),
515 ParamLoweringMode::Variable => {
516 generics.bound_vars_subst(self.db, self.in_binders)
519 self.db.ty(adt.into()).substitute(Interner, &substs)
522 TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args),
523 TypeNs::BuiltinType(it) => {
524 self.lower_path_inner(resolved_segment, it.into(), infer_args)
526 TypeNs::TypeAliasId(it) => {
527 self.lower_path_inner(resolved_segment, it.into(), infer_args)
529 // FIXME: report error
530 TypeNs::EnumVariantId(_) => return (TyKind::Error.intern(Interner), None),
532 self.lower_ty_relative_path(ty, Some(resolution), remaining_segments)
535 pub(crate) fn lower_path(&self, path: &Path) -> (Ty, Option<TypeNs>) {
536 // Resolve the path (in type namespace)
537 if let Some(type_ref) = path.type_anchor() {
538 let (ty, res) = self.lower_ty_ext(type_ref);
539 return self.lower_ty_relative_path(ty, res, path.segments());
542 let (resolution, remaining_index) =
543 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
545 None => return (TyKind::Error.intern(Interner), None),
548 if matches!(resolution, TypeNs::TraitId(_)) && remaining_index.is_none() {
549 // trait object type without dyn
550 let bound = TypeBound::Path(path.clone(), TraitBoundModifier::None);
551 let ty = self.lower_dyn_trait(&[Interned::new(bound)]);
555 let (resolved_segment, remaining_segments) = match remaining_index {
557 path.segments().last().expect("resolved path has at least one element"),
560 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)),
562 self.lower_partly_resolved_path(resolution, resolved_segment, remaining_segments, false)
565 fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
566 let (def, res) = match (self.resolver.generic_def(), res) {
567 (Some(def), Some(res)) => (def, res),
568 _ => return TyKind::Error.intern(Interner),
570 let ty = named_associated_type_shorthand_candidates(
574 Some(segment.name.clone()),
575 move |name, t, associated_ty| {
576 if name == segment.name {
577 let substs = match self.type_param_mode {
578 ParamLoweringMode::Placeholder => {
579 // if we're lowering to placeholders, we have to put
581 let generics = generics(
585 .expect("there should be generics if there's a generic param"),
587 let s = generics.placeholder_subst(self.db);
588 s.apply(t.substitution.clone(), Interner)
590 ParamLoweringMode::Variable => t.substitution.clone(),
592 // We need to shift in the bound vars, since
593 // associated_type_shorthand_candidates does not do that
594 let substs = substs.shifted_in_from(Interner, self.in_binders);
595 // FIXME handle type parameters on the segment
597 TyKind::Alias(AliasTy::Projection(ProjectionTy {
598 associated_ty_id: to_assoc_type_id(associated_ty),
599 substitution: substs,
609 ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
614 segment: PathSegment<'_>,
618 let generic_def = match typeable {
619 TyDefId::BuiltinType(_) => None,
620 TyDefId::AdtId(it) => Some(it.into()),
621 TyDefId::TypeAliasId(it) => Some(it.into()),
623 let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None);
624 self.db.ty(typeable).substitute(Interner, &substs)
627 /// Collect generic arguments from a path into a `Substs`. See also
628 /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
629 pub(super) fn substs_from_path(
632 // Note that we don't call `db.value_type(resolved)` here,
633 // `ValueTyDefId` is just a convenient way to pass generics and
634 // special-case enum variants
635 resolved: ValueTyDefId,
638 let last = path.segments().last().expect("path should have at least one segment");
639 let (segment, generic_def) = match resolved {
640 ValueTyDefId::FunctionId(it) => (last, Some(it.into())),
641 ValueTyDefId::StructId(it) => (last, Some(it.into())),
642 ValueTyDefId::UnionId(it) => (last, Some(it.into())),
643 ValueTyDefId::ConstId(it) => (last, Some(it.into())),
644 ValueTyDefId::StaticId(_) => (last, None),
645 ValueTyDefId::EnumVariantId(var) => {
646 // the generic args for an enum variant may be either specified
647 // on the segment referring to the enum, or on the segment
648 // referring to the variant. So `Option::<T>::None` and
649 // `Option::None::<T>` are both allowed (though the former is
650 // preferred). See also `def_ids_for_path_segments` in rustc.
651 let len = path.segments().len();
652 let penultimate = len.checked_sub(2).and_then(|idx| path.segments().get(idx));
653 let segment = match penultimate {
654 Some(segment) if segment.args_and_bindings.is_some() => segment,
657 (segment, Some(var.parent.into()))
660 self.substs_from_path_segment(segment, generic_def, infer_args, None)
663 fn substs_from_path_segment(
665 segment: PathSegment<'_>,
666 def_generic: Option<GenericDefId>,
668 explicit_self_ty: Option<Ty>,
670 let mut substs = Vec::new();
671 let def_generics = if let Some(def) = def_generic {
672 generics(self.db.upcast(), def)
674 return Substitution::empty(Interner);
676 let (parent_params, self_params, type_params, const_params, impl_trait_params) =
677 def_generics.provenance_split();
679 parent_params + self_params + type_params + const_params + impl_trait_params;
681 let ty_error = GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner);
683 let mut def_generic_iter = def_generics.iter_id();
685 for _ in 0..parent_params {
686 if let Some(eid) = def_generic_iter.next() {
688 Either::Left(_) => substs.push(ty_error.clone()),
689 Either::Right(x) => {
690 substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
696 let fill_self_params = || {
697 for x in explicit_self_ty
699 .map(|x| GenericArgData::Ty(x).intern(Interner))
700 .chain(iter::repeat(ty_error.clone()))
703 if let Some(id) = def_generic_iter.next() {
704 assert!(id.is_left());
709 let mut had_explicit_args = false;
711 if let Some(generic_args) = &segment.args_and_bindings {
712 if !generic_args.has_self_type {
715 let expected_num = if generic_args.has_self_type {
716 self_params + type_params + const_params
718 type_params + const_params
720 let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
721 // if args are provided, it should be all of them, but we can't rely on that
722 for arg in generic_args
725 .filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
729 if let Some(id) = def_generic_iter.next() {
730 if let Some(x) = generic_arg_to_chalk(
735 |_, type_ref| self.lower_ty(type_ref),
737 const_or_path_to_chalk(
742 self.type_param_mode,
748 had_explicit_args = true;
751 // we just filtered them out
752 never!("Unexpected lifetime argument");
760 // handle defaults. In expression or pattern path segments without
761 // explicitly specified type arguments, missing type arguments are inferred
762 // (i.e. defaults aren't used).
763 if !infer_args || had_explicit_args {
764 if let Some(def_generic) = def_generic {
765 let defaults = self.db.generic_defaults(def_generic);
766 assert_eq!(total_len, defaults.len());
768 for default_ty in defaults.iter().skip(substs.len()) {
769 // each default can depend on the previous parameters
770 let substs_so_far = Substitution::from_iter(Interner, substs.clone());
771 if let Some(_id) = def_generic_iter.next() {
772 substs.push(default_ty.clone().substitute(Interner, &substs_so_far));
778 // add placeholders for args that were not provided
779 // FIXME: emit diagnostics in contexts where this is not allowed
780 for eid in def_generic_iter {
782 Either::Left(_) => substs.push(ty_error.clone()),
783 Either::Right(x) => {
784 substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
788 // If this assert fails, it means you pushed into subst but didn't call .next() of def_generic_iter
789 assert_eq!(substs.len(), total_len);
791 Substitution::from_iter(Interner, substs)
794 fn lower_trait_ref_from_path(
797 explicit_self_ty: Option<Ty>,
798 ) -> Option<TraitRef> {
800 match self.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), path.mod_path())? {
801 TypeNs::TraitId(tr) => tr,
804 let segment = path.segments().last().expect("path should have at least one segment");
805 Some(self.lower_trait_ref_from_resolved_path(resolved, segment, explicit_self_ty))
808 pub(crate) fn lower_trait_ref_from_resolved_path(
811 segment: PathSegment<'_>,
812 explicit_self_ty: Option<Ty>,
814 let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
815 TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
820 trait_ref: &HirTraitRef,
821 explicit_self_ty: Option<Ty>,
822 ) -> Option<TraitRef> {
823 self.lower_trait_ref_from_path(&trait_ref.path, explicit_self_ty)
826 fn trait_ref_substs_from_path(
828 segment: PathSegment<'_>,
830 explicit_self_ty: Option<Ty>,
832 self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
835 pub(crate) fn lower_where_predicate(
837 where_predicate: &'a WherePredicate,
838 ignore_bindings: bool,
839 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
840 match where_predicate {
841 WherePredicate::ForLifetime { target, bound, .. }
842 | WherePredicate::TypeBound { target, bound } => {
843 let self_ty = match target {
844 WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
845 WherePredicateTypeTarget::TypeOrConstParam(param_id) => {
846 let generic_def = self.resolver.generic_def().expect("generics in scope");
847 let generics = generics(self.db.upcast(), generic_def);
848 let param_id = hir_def::TypeOrConstParamId {
852 let placeholder = to_placeholder_idx(self.db, param_id);
853 match self.type_param_mode {
854 ParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder),
855 ParamLoweringMode::Variable => {
856 let idx = generics.param_idx(param_id).expect("matching generics");
857 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
863 self.lower_type_bound(bound, self_ty, ignore_bindings)
867 WherePredicate::Lifetime { .. } => vec![].into_iter(),
871 pub(crate) fn lower_type_bound(
873 bound: &'a TypeBound,
875 ignore_bindings: bool,
876 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
877 let mut bindings = None;
878 let trait_ref = match bound {
879 TypeBound::Path(path, TraitBoundModifier::None) => {
880 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
884 // ignore `T: Drop` or `T: Destruct` bounds.
885 // - `T: ~const Drop` has a special meaning in Rust 1.61 that we don't implement.
886 // (So ideally, we'd only ignore `~const Drop` here)
887 // - `Destruct` impls are built-in in 1.62 (current nightlies as of 08-04-2022), so until
888 // the builtin impls are supported by Chalk, we ignore them here.
889 if let Some(lang) = lang_attr(self.db.upcast(), tr.hir_trait_id()) {
890 if lang == "drop" || lang == "destruct" {
896 .map(WhereClause::Implemented)
897 .map(crate::wrap_empty_binders)
899 TypeBound::Path(path, TraitBoundModifier::Maybe) => {
900 let sized_trait = self
902 .lang_item(self.resolver.krate(), SmolStr::new_inline("sized"))
903 .and_then(|lang_item| lang_item.as_trait());
904 // Don't lower associated type bindings as the only possible relaxed trait bound
905 // `?Sized` has no of them.
906 // If we got another trait here ignore the bound completely.
908 .lower_trait_ref_from_path(path, Some(self_ty.clone()))
909 .map(|trait_ref| trait_ref.hir_trait_id());
910 if trait_id == sized_trait {
911 self.unsized_types.borrow_mut().insert(self_ty);
915 TypeBound::ForLifetime(_, path) => {
916 // FIXME Don't silently drop the hrtb lifetimes here
917 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
918 bindings.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
920 TypeBound::Lifetime(_) => None,
921 TypeBound::Error => None,
923 trait_ref.into_iter().chain(
926 .filter(move |_| !ignore_bindings)
927 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)),
931 fn assoc_type_bindings_from_type_bound(
933 bound: &'a TypeBound,
935 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
936 let last_segment = match bound {
937 TypeBound::Path(path, TraitBoundModifier::None) | TypeBound::ForLifetime(_, path) => {
938 path.segments().last()
940 TypeBound::Path(_, TraitBoundModifier::Maybe)
942 | TypeBound::Lifetime(_) => None,
946 .filter_map(|segment| segment.args_and_bindings)
947 .flat_map(|args_and_bindings| &args_and_bindings.bindings)
948 .flat_map(move |binding| {
949 let found = associated_type_by_name_including_super_traits(
954 let (super_trait_ref, associated_ty) = match found {
955 None => return SmallVec::new(),
958 let projection_ty = ProjectionTy {
959 associated_ty_id: to_assoc_type_id(associated_ty),
960 substitution: super_trait_ref.substitution,
962 let mut preds: SmallVec<[_; 1]> = SmallVec::with_capacity(
963 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
965 if let Some(type_ref) = &binding.type_ref {
966 let ty = self.lower_ty(type_ref);
968 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
969 preds.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
971 for bound in &binding.bounds {
972 preds.extend(self.lower_type_bound(
974 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(Interner),
982 fn lower_dyn_trait(&self, bounds: &[Interned<TypeBound>]) -> Ty {
983 let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
984 // INVARIANT: The principal trait bound must come first. Others may be in any order but
985 // should be in the same order for the same set but possibly different order of bounds in
987 // This invariant is used by `TyExt::dyn_trait()` and chalk.
988 let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
989 let mut bounds: Vec<_> = bounds
991 .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
994 let mut multiple_regular_traits = false;
995 let mut multiple_same_projection = false;
996 bounds.sort_unstable_by(|lhs, rhs| {
997 use std::cmp::Ordering;
998 match (lhs.skip_binders(), rhs.skip_binders()) {
999 (WhereClause::Implemented(lhs), WhereClause::Implemented(rhs)) => {
1000 let lhs_id = lhs.trait_id;
1001 let lhs_is_auto = ctx.db.trait_data(from_chalk_trait_id(lhs_id)).is_auto;
1002 let rhs_id = rhs.trait_id;
1003 let rhs_is_auto = ctx.db.trait_data(from_chalk_trait_id(rhs_id)).is_auto;
1005 if !lhs_is_auto && !rhs_is_auto {
1006 multiple_regular_traits = true;
1008 // Note that the ordering here is important; this ensures the invariant
1010 (lhs_is_auto, lhs_id).cmp(&(rhs_is_auto, rhs_id))
1012 (WhereClause::Implemented(_), _) => Ordering::Less,
1013 (_, WhereClause::Implemented(_)) => Ordering::Greater,
1014 (WhereClause::AliasEq(lhs), WhereClause::AliasEq(rhs)) => {
1015 match (&lhs.alias, &rhs.alias) {
1016 (AliasTy::Projection(lhs_proj), AliasTy::Projection(rhs_proj)) => {
1017 // We only compare the `associated_ty_id`s. We shouldn't have
1018 // multiple bounds for an associated type in the correct Rust code,
1019 // and if we do, we error out.
1020 if lhs_proj.associated_ty_id == rhs_proj.associated_ty_id {
1021 multiple_same_projection = true;
1023 lhs_proj.associated_ty_id.cmp(&rhs_proj.associated_ty_id)
1025 // We don't produce `AliasTy::Opaque`s yet.
1026 _ => unreachable!(),
1029 // We don't produce `WhereClause::{TypeOutlives, LifetimeOutlives}` yet.
1030 _ => unreachable!(),
1034 if multiple_regular_traits || multiple_same_projection {
1038 // As multiple occurrences of the same auto traits *are* permitted, we dedulicate the
1039 // bounds. We shouldn't have repeated elements besides auto traits at this point.
1042 Some(QuantifiedWhereClauses::from_iter(Interner, bounds))
1045 if let Some(bounds) = bounds {
1046 let bounds = crate::make_single_type_binders(bounds);
1047 TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
1049 // FIXME: report error (additional non-auto traits or associated type rebound)
1050 TyKind::Error.intern(Interner)
1054 fn lower_impl_trait(
1056 bounds: &[Interned<TypeBound>],
1058 ) -> ReturnTypeImplTrait {
1059 cov_mark::hit!(lower_rpit);
1060 let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
1061 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
1062 let mut predicates: Vec<_> = bounds
1064 .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
1067 if !ctx.unsized_types.borrow().contains(&self_ty) {
1068 let krate = func.lookup(ctx.db.upcast()).module(ctx.db.upcast()).krate();
1069 let sized_trait = ctx
1071 .lang_item(krate, SmolStr::new_inline("sized"))
1072 .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1073 let sized_clause = sized_trait.map(|trait_id| {
1074 let clause = WhereClause::Implemented(TraitRef {
1076 substitution: Substitution::from1(Interner, self_ty.clone()),
1078 crate::wrap_empty_binders(clause)
1080 predicates.extend(sized_clause.into_iter());
1081 predicates.shrink_to_fit();
1085 ReturnTypeImplTrait { bounds: crate::make_single_type_binders(predicates) }
1089 fn count_impl_traits(type_ref: &TypeRef) -> usize {
1091 type_ref.walk(&mut |type_ref| {
1092 if matches!(type_ref, TypeRef::ImplTrait(_)) {
1099 /// Build the signature of a callable item (function, struct or enum variant).
1100 pub(crate) fn callable_item_sig(db: &dyn HirDatabase, def: CallableDefId) -> PolyFnSig {
1102 CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f),
1103 CallableDefId::StructId(s) => fn_sig_for_struct_constructor(db, s),
1104 CallableDefId::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e),
1108 pub fn associated_type_shorthand_candidates<R>(
1109 db: &dyn HirDatabase,
1112 cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
1114 named_associated_type_shorthand_candidates(db, def, res, None, cb)
1117 fn named_associated_type_shorthand_candidates<R>(
1118 db: &dyn HirDatabase,
1119 // If the type parameter is defined in an impl and we're in a method, there
1120 // might be additional where clauses to consider
1123 assoc_name: Option<Name>,
1124 mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
1126 let mut search = |t| {
1127 for t in all_super_trait_refs(db, t) {
1128 let data = db.trait_data(t.hir_trait_id());
1130 for (name, assoc_id) in &data.items {
1131 if let AssocItemId::TypeAliasId(alias) = assoc_id {
1132 if let Some(result) = cb(name, &t, *alias) {
1133 return Some(result);
1142 TypeNs::SelfType(impl_id) => search(
1143 // we're _in_ the impl -- the binders get added back later. Correct,
1144 // but it would be nice to make this more explicit
1145 db.impl_trait(impl_id)?.into_value_and_skipped_binders().0,
1147 TypeNs::GenericParam(param_id) => {
1148 let predicates = db.generic_predicates_for_param(def, param_id.into(), assoc_name);
1149 let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
1150 // FIXME: how to correctly handle higher-ranked bounds here?
1151 WhereClause::Implemented(tr) => search(
1153 .shifted_out_to(Interner, DebruijnIndex::ONE)
1154 .expect("FIXME unexpected higher-ranked trait bound"),
1158 if let Some(_) = res {
1161 // Handle `Self::Type` referring to own associated type in trait definitions
1162 if let GenericDefId::TraitId(trait_id) = param_id.parent() {
1163 let generics = generics(db.upcast(), trait_id.into());
1164 if generics.params.type_or_consts[param_id.local_id()].is_trait_self() {
1165 let trait_ref = TyBuilder::trait_ref(db, trait_id)
1166 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
1168 return search(trait_ref);
1177 /// Build the type of all specific fields of a struct or enum variant.
1178 pub(crate) fn field_types_query(
1179 db: &dyn HirDatabase,
1180 variant_id: VariantId,
1181 ) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> {
1182 let var_data = variant_id.variant_data(db.upcast());
1183 let (resolver, def): (_, GenericDefId) = match variant_id {
1184 VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()),
1185 VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()),
1186 VariantId::EnumVariantId(it) => (it.parent.resolver(db.upcast()), it.parent.into()),
1188 let generics = generics(db.upcast(), def);
1189 let mut res = ArenaMap::default();
1191 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1192 for (field_id, field_data) in var_data.fields().iter() {
1193 res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref)));
1198 /// This query exists only to be used when resolving short-hand associated types
1201 /// See the analogous query in rustc and its comment:
1202 /// <https://github.com/rust-lang/rust/blob/9150f844e2624eb013ec78ca08c1d416e6644026/src/librustc_typeck/astconv.rs#L46>
1203 /// This is a query mostly to handle cycles somewhat gracefully; e.g. the
1204 /// following bounds are disallowed: `T: Foo<U::Item>, U: Foo<T::Item>`, but
1205 /// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
1206 pub(crate) fn generic_predicates_for_param_query(
1207 db: &dyn HirDatabase,
1209 param_id: TypeOrConstParamId,
1210 assoc_name: Option<Name>,
1211 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1212 let resolver = def.resolver(db.upcast());
1214 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1215 let generics = generics(db.upcast(), def);
1216 let mut predicates: Vec<_> = resolver
1217 .where_predicates_in_scope()
1218 // we have to filter out all other predicates *first*, before attempting to lower them
1219 .filter(|pred| match pred {
1220 WherePredicate::ForLifetime { target, bound, .. }
1221 | WherePredicate::TypeBound { target, bound, .. } => {
1223 WherePredicateTypeTarget::TypeRef(type_ref) => {
1224 if ctx.lower_ty_only_param(type_ref) != Some(param_id) {
1228 &WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
1229 let target_id = TypeOrConstParamId { parent: def, local_id };
1230 if target_id != param_id {
1237 TypeBound::ForLifetime(_, path) | TypeBound::Path(path, _) => {
1238 // Only lower the bound if the trait could possibly define the associated
1239 // type we're looking for.
1241 let assoc_name = match &assoc_name {
1243 None => return true,
1245 let tr = match resolver
1246 .resolve_path_in_type_ns_fully(db.upcast(), path.mod_path())
1248 Some(TypeNs::TraitId(tr)) => tr,
1252 all_super_traits(db.upcast(), tr).iter().any(|tr| {
1253 db.trait_data(*tr).items.iter().any(|(name, item)| {
1254 matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name
1258 TypeBound::Lifetime(_) | TypeBound::Error => false,
1261 WherePredicate::Lifetime { .. } => false,
1264 ctx.lower_where_predicate(pred, true).map(|p| make_binders(db, &generics, p))
1268 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1269 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1270 let implicitly_sized_predicates =
1271 implicitly_sized_clauses(db, param_id.parent, &explicitly_unsized_tys, &subst, &resolver)
1272 .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1273 predicates.extend(implicitly_sized_predicates);
1277 pub(crate) fn generic_predicates_for_param_recover(
1278 _db: &dyn HirDatabase,
1280 _def: &GenericDefId,
1281 _param_id: &TypeOrConstParamId,
1282 _assoc_name: &Option<Name>,
1283 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1287 pub(crate) fn trait_environment_query(
1288 db: &dyn HirDatabase,
1290 ) -> Arc<TraitEnvironment> {
1291 let resolver = def.resolver(db.upcast());
1293 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Placeholder);
1294 let mut traits_in_scope = Vec::new();
1295 let mut clauses = Vec::new();
1296 for pred in resolver.where_predicates_in_scope() {
1297 for pred in ctx.lower_where_predicate(pred, false) {
1298 if let WhereClause::Implemented(tr) = &pred.skip_binders() {
1299 traits_in_scope.push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id()));
1301 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1302 clauses.push(program_clause.into_from_env_clause(Interner));
1306 let container: Option<ItemContainerId> = match def {
1307 // FIXME: is there a function for this?
1308 GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
1309 GenericDefId::AdtId(_) => None,
1310 GenericDefId::TraitId(_) => None,
1311 GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container),
1312 GenericDefId::ImplId(_) => None,
1313 GenericDefId::EnumVariantId(_) => None,
1314 GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container),
1316 if let Some(ItemContainerId::TraitId(trait_id)) = container {
1317 // add `Self: Trait<T1, T2, ...>` to the environment in trait
1318 // function default implementations (and speculative code
1319 // inside consts or type aliases)
1320 cov_mark::hit!(trait_self_implements_self);
1321 let substs = TyBuilder::placeholder_subst(db, trait_id);
1322 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
1323 let pred = WhereClause::Implemented(trait_ref);
1324 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1325 clauses.push(program_clause.into_from_env_clause(Interner));
1328 let subst = generics(db.upcast(), def).placeholder_subst(db);
1329 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1330 let implicitly_sized_clauses =
1331 implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver).map(|pred| {
1332 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
1333 program_clause.into_from_env_clause(Interner)
1335 clauses.extend(implicitly_sized_clauses);
1337 let krate = def.module(db.upcast()).krate();
1339 let env = chalk_ir::Environment::new(Interner).add_clauses(Interner, clauses);
1341 Arc::new(TraitEnvironment { krate, traits_from_clauses: traits_in_scope, env })
1344 /// Resolve the where clause(s) of an item with generics.
1345 pub(crate) fn generic_predicates_query(
1346 db: &dyn HirDatabase,
1348 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
1349 let resolver = def.resolver(db.upcast());
1351 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1352 let generics = generics(db.upcast(), def);
1354 let mut predicates = resolver
1355 .where_predicates_in_scope()
1357 ctx.lower_where_predicate(pred, false).map(|p| make_binders(db, &generics, p))
1359 .collect::<Vec<_>>();
1361 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1362 let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1363 let implicitly_sized_predicates =
1364 implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver)
1365 .map(|p| make_binders(db, &generics, crate::wrap_empty_binders(p)));
1366 predicates.extend(implicitly_sized_predicates);
1370 /// Generate implicit `: Sized` predicates for all generics that has no `?Sized` bound.
1371 /// Exception is Self of a trait def.
1372 fn implicitly_sized_clauses<'a>(
1373 db: &dyn HirDatabase,
1375 explicitly_unsized_tys: &'a FxHashSet<Ty>,
1376 substitution: &'a Substitution,
1377 resolver: &Resolver,
1378 ) -> impl Iterator<Item = WhereClause> + 'a {
1379 let is_trait_def = matches!(def, GenericDefId::TraitId(..));
1380 let generic_args = &substitution.as_slice(Interner)[is_trait_def as usize..];
1381 let sized_trait = db
1382 .lang_item(resolver.krate(), SmolStr::new_inline("sized"))
1383 .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
1385 sized_trait.into_iter().flat_map(move |sized_trait| {
1386 let implicitly_sized_tys = generic_args
1388 .filter_map(|generic_arg| generic_arg.ty(Interner))
1389 .filter(move |&self_ty| !explicitly_unsized_tys.contains(self_ty));
1390 implicitly_sized_tys.map(move |self_ty| {
1391 WhereClause::Implemented(TraitRef {
1392 trait_id: sized_trait,
1393 substitution: Substitution::from1(Interner, self_ty.clone()),
1399 /// Resolve the default type params from generics
1400 pub(crate) fn generic_defaults_query(
1401 db: &dyn HirDatabase,
1403 ) -> Arc<[Binders<chalk_ir::GenericArg<Interner>>]> {
1404 let resolver = def.resolver(db.upcast());
1406 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1407 let generic_params = generics(db.upcast(), def);
1409 let defaults = generic_params
1412 .map(|(idx, (id, p))| {
1414 TypeOrConstParamData::TypeParamData(p) => p,
1415 TypeOrConstParamData::ConstParamData(_) => {
1416 // FIXME: implement const generic defaults
1417 let val = unknown_const_as_generic(
1418 db.const_param_ty(ConstParamId::from_unchecked(id)),
1420 return crate::make_binders_with_count(db, idx, &generic_params, val);
1424 p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
1426 // Each default can only refer to previous parameters.
1427 // type variable default referring to parameter coming
1428 // after it. This is forbidden (FIXME: report
1430 ty = fallback_bound_vars(ty, idx);
1431 let val = GenericArgData::Ty(ty).intern(Interner);
1432 crate::make_binders_with_count(db, idx, &generic_params, val)
1439 pub(crate) fn generic_defaults_recover(
1440 db: &dyn HirDatabase,
1443 ) -> Arc<[Binders<crate::GenericArg>]> {
1444 let generic_params = generics(db.upcast(), *def);
1445 // FIXME: this code is not covered in tests.
1446 // we still need one default per parameter
1447 let defaults = generic_params
1450 .map(|(count, id)| {
1451 let val = match id {
1452 itertools::Either::Left(_) => {
1453 GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1455 itertools::Either::Right(id) => unknown_const_as_generic(db.const_param_ty(id)),
1457 crate::make_binders_with_count(db, count, &generic_params, val)
1464 fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1465 let data = db.function_data(def);
1466 let resolver = def.resolver(db.upcast());
1467 let ctx_params = TyLoweringContext::new(db, &resolver)
1468 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
1469 .with_type_param_mode(ParamLoweringMode::Variable);
1470 let params = data.params.iter().map(|(_, tr)| ctx_params.lower_ty(tr)).collect::<Vec<_>>();
1471 let ctx_ret = TyLoweringContext::new(db, &resolver)
1472 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1473 .with_type_param_mode(ParamLoweringMode::Variable);
1474 let ret = ctx_ret.lower_ty(&data.ret_type);
1475 let generics = generics(db.upcast(), def.into());
1476 let sig = CallableSig::from_params_and_return(params, ret, data.is_varargs());
1477 make_binders(db, &generics, sig)
1480 /// Build the declared type of a function. This should not need to look at the
1482 fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1483 let generics = generics(db.upcast(), def.into());
1484 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1488 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(Interner),
1492 /// Build the declared type of a const.
1493 fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
1494 let data = db.const_data(def);
1495 let generics = generics(db.upcast(), def.into());
1496 let resolver = def.resolver(db.upcast());
1498 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1500 make_binders(db, &generics, ctx.lower_ty(&data.type_ref))
1503 /// Build the declared type of a static.
1504 fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
1505 let data = db.static_data(def);
1506 let resolver = def.resolver(db.upcast());
1507 let ctx = TyLoweringContext::new(db, &resolver);
1509 Binders::empty(Interner, ctx.lower_ty(&data.type_ref))
1512 fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
1513 let struct_data = db.struct_data(def);
1514 let fields = struct_data.variant_data.fields();
1515 let resolver = def.resolver(db.upcast());
1517 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1518 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1519 let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
1520 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1523 /// Build the type of a tuple struct constructor.
1524 fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<Ty> {
1525 let struct_data = db.struct_data(def);
1526 if let StructKind::Unit = struct_data.variant_data.kind() {
1527 return type_for_adt(db, def.into());
1529 let generics = generics(db.upcast(), def.into());
1530 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1534 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
1538 fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
1539 let enum_data = db.enum_data(def.parent);
1540 let var_data = &enum_data.variants[def.local_id];
1541 let fields = var_data.variant_data.fields();
1542 let resolver = def.parent.resolver(db.upcast());
1544 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1545 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1546 let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
1547 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1550 /// Build the type of a tuple enum variant constructor.
1551 fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> Binders<Ty> {
1552 let enum_data = db.enum_data(def.parent);
1553 let var_data = &enum_data.variants[def.local_id].variant_data;
1554 if let StructKind::Unit = var_data.kind() {
1555 return type_for_adt(db, def.parent.into());
1557 let generics = generics(db.upcast(), def.parent.into());
1558 let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1562 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(Interner),
1566 fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1567 let generics = generics(db.upcast(), adt.into());
1568 let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1569 let ty = TyKind::Adt(crate::AdtId(adt), subst).intern(Interner);
1570 make_binders(db, &generics, ty)
1573 fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1574 let generics = generics(db.upcast(), t.into());
1575 let resolver = t.resolver(db.upcast());
1577 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1578 if db.type_alias_data(t).is_extern {
1579 Binders::empty(Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner))
1581 let type_ref = &db.type_alias_data(t).type_ref;
1582 let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
1583 make_binders(db, &generics, inner)
1587 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1588 pub enum CallableDefId {
1589 FunctionId(FunctionId),
1591 EnumVariantId(EnumVariantId),
1593 impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
1595 impl CallableDefId {
1596 pub fn krate(self, db: &dyn HirDatabase) -> CrateId {
1597 let db = db.upcast();
1599 CallableDefId::FunctionId(f) => f.lookup(db).module(db),
1600 CallableDefId::StructId(s) => s.lookup(db).container,
1601 CallableDefId::EnumVariantId(e) => e.parent.lookup(db).container,
1607 impl From<CallableDefId> for GenericDefId {
1608 fn from(def: CallableDefId) -> GenericDefId {
1610 CallableDefId::FunctionId(f) => f.into(),
1611 CallableDefId::StructId(s) => s.into(),
1612 CallableDefId::EnumVariantId(e) => e.into(),
1617 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1619 BuiltinType(BuiltinType),
1621 TypeAliasId(TypeAliasId),
1623 impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
1625 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1626 pub enum ValueTyDefId {
1627 FunctionId(FunctionId),
1630 EnumVariantId(EnumVariantId),
1634 impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
1636 /// Build the declared type of an item. This depends on the namespace; e.g. for
1637 /// `struct Foo(usize)`, we have two types: The type of the struct itself, and
1638 /// the constructor function `(usize) -> Foo` which lives in the values
1640 pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
1642 TyDefId::BuiltinType(it) => Binders::empty(Interner, TyBuilder::builtin(it)),
1643 TyDefId::AdtId(it) => type_for_adt(db, it),
1644 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
1648 pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> {
1649 let generics = match *def {
1650 TyDefId::BuiltinType(_) => return Binders::empty(Interner, TyKind::Error.intern(Interner)),
1651 TyDefId::AdtId(it) => generics(db.upcast(), it.into()),
1652 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()),
1654 make_binders(db, &generics, TyKind::Error.intern(Interner))
1657 pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
1659 ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
1660 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
1661 ValueTyDefId::UnionId(it) => type_for_adt(db, it.into()),
1662 ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
1663 ValueTyDefId::ConstId(it) => type_for_const(db, it),
1664 ValueTyDefId::StaticId(it) => type_for_static(db, it),
1668 pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> {
1669 let impl_loc = impl_id.lookup(db.upcast());
1670 let impl_data = db.impl_data(impl_id);
1671 let resolver = impl_id.resolver(db.upcast());
1672 let _cx = stdx::panic_context::enter(format!(
1673 "impl_self_ty_query({:?} -> {:?} -> {:?})",
1674 impl_id, impl_loc, impl_data
1676 let generics = generics(db.upcast(), impl_id.into());
1678 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1679 make_binders(db, &generics, ctx.lower_ty(&impl_data.self_ty))
1682 // returns None if def is a type arg
1683 pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
1684 let parent_data = db.generic_params(def.parent());
1685 let data = &parent_data.type_or_consts[def.local_id()];
1686 let resolver = def.parent().resolver(db.upcast());
1687 let ctx = TyLoweringContext::new(db, &resolver);
1689 TypeOrConstParamData::TypeParamData(_) => {
1691 Ty::new(Interner, TyKind::Error)
1693 TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(&d.ty),
1697 pub(crate) fn impl_self_ty_recover(
1698 db: &dyn HirDatabase,
1702 let generics = generics(db.upcast(), (*impl_id).into());
1703 make_binders(db, &generics, TyKind::Error.intern(Interner))
1706 pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
1707 let impl_loc = impl_id.lookup(db.upcast());
1708 let impl_data = db.impl_data(impl_id);
1709 let resolver = impl_id.resolver(db.upcast());
1710 let _cx = stdx::panic_context::enter(format!(
1711 "impl_trait_query({:?} -> {:?} -> {:?})",
1712 impl_id, impl_loc, impl_data
1715 TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
1716 let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
1717 let target_trait = impl_data.target_trait.as_ref()?;
1718 Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
1721 pub(crate) fn return_type_impl_traits(
1722 db: &dyn HirDatabase,
1723 def: hir_def::FunctionId,
1724 ) -> Option<Arc<Binders<ReturnTypeImplTraits>>> {
1725 // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
1726 let data = db.function_data(def);
1727 let resolver = def.resolver(db.upcast());
1728 let ctx_ret = TyLoweringContext::new(db, &resolver)
1729 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1730 .with_type_param_mode(ParamLoweringMode::Variable);
1731 let _ret = (&ctx_ret).lower_ty(&data.ret_type);
1732 let generics = generics(db.upcast(), def.into());
1733 let return_type_impl_traits =
1734 ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() };
1735 if return_type_impl_traits.impl_traits.is_empty() {
1738 Some(Arc::new(make_binders(db, &generics, return_type_impl_traits)))
1742 pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mutability {
1744 hir_def::type_ref::Mutability::Shared => Mutability::Not,
1745 hir_def::type_ref::Mutability::Mut => Mutability::Mut,
1749 /// Checks if the provided generic arg matches its expected kind, then lower them via
1750 /// provided closures. Use unknown if there was kind mismatch.
1752 /// Returns `Some` of the lowered generic arg. `None` if the provided arg is a lifetime.
1753 pub(crate) fn generic_arg_to_chalk<'a, T>(
1754 db: &dyn HirDatabase,
1755 kind_id: Either<TypeParamId, ConstParamId>,
1756 arg: &'a GenericArg,
1758 for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a,
1759 for_const: impl FnOnce(&mut T, &ConstScalarOrPath, Ty) -> Const + 'a,
1760 ) -> Option<crate::GenericArg> {
1761 let kind = match kind_id {
1762 Either::Left(_) => ParamKind::Type,
1763 Either::Right(id) => {
1764 let ty = db.const_param_ty(id);
1765 ParamKind::Const(ty)
1768 Some(match (arg, kind) {
1769 (GenericArg::Type(type_ref), ParamKind::Type) => {
1770 let ty = for_type(this, type_ref);
1771 GenericArgData::Ty(ty).intern(Interner)
1773 (GenericArg::Const(c), ParamKind::Const(c_ty)) => {
1774 GenericArgData::Const(for_const(this, c, c_ty)).intern(Interner)
1776 (GenericArg::Const(_), ParamKind::Type) => {
1777 GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
1779 (GenericArg::Type(t), ParamKind::Const(c_ty)) => {
1780 // We want to recover simple idents, which parser detects them
1781 // as types. Maybe here is not the best place to do it, but
1783 if let TypeRef::Path(p) = t {
1784 let p = p.mod_path();
1785 if p.kind == PathKind::Plain {
1786 if let [n] = p.segments() {
1787 let c = ConstScalarOrPath::Path(n.clone());
1789 GenericArgData::Const(for_const(this, &c, c_ty)).intern(Interner),
1794 unknown_const_as_generic(c_ty)
1796 (GenericArg::Lifetime(_), _) => return None,
1800 pub(crate) fn const_or_path_to_chalk(
1801 db: &dyn HirDatabase,
1802 resolver: &Resolver,
1804 value: &ConstScalarOrPath,
1805 mode: ParamLoweringMode,
1806 args: impl FnOnce() -> Generics,
1807 debruijn: DebruijnIndex,
1810 ConstScalarOrPath::Scalar(s) => intern_const_scalar(s.clone(), expected_ty),
1811 ConstScalarOrPath::Path(n) => {
1812 let path = ModPath::from_segments(PathKind::Plain, Some(n.clone()));
1813 path_to_const(db, resolver, &path, mode, args, debruijn)
1814 .unwrap_or_else(|| unknown_const(expected_ty))
1819 /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
1820 /// num_vars_to_keep) by `TyKind::Unknown`.
1821 fn fallback_bound_vars<T: TypeFoldable<Interner> + HasInterner<Interner = Interner>>(
1823 num_vars_to_keep: usize,
1825 crate::fold_free_vars(
1828 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1829 TyKind::Error.intern(Interner)
1831 bound.shifted_in_from(binders).to_ty(Interner)
1834 |ty, bound, binders| {
1835 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1836 unknown_const(ty.clone())
1838 bound.shifted_in_from(binders).to_const(Interner, ty)