1 //! Type inference, i.e. the process of walking through the code and determining
2 //! the type of each expression and pattern.
4 //! For type inference, compare the implementations in rustc (the various
5 //! check_* methods in rustc_hir_analysis/check/mod.rs are a good entry point) and
6 //! IntelliJ-Rust (org.rust.lang.core.types.infer). Our entry point for
7 //! inference here is the `infer` function, which infers the types of all
8 //! expressions in a given function.
10 //! During inference, types (i.e. the `Ty` struct) can contain type 'variables'
11 //! which represent currently unknown types; as we walk through the expressions,
12 //! we might determine that certain variables need to be equal to each other, or
13 //! to certain types. To record this, we use the union-find implementation from
14 //! the `ena` crate, which is extracted from rustc.
19 use chalk_ir::{cast::Cast, ConstValue, DebruijnIndex, Mutability, Safety, Scalar, TypeFlags};
22 data::{ConstData, StaticData},
23 expr::{BindingAnnotation, ExprId, PatId},
24 lang_item::LangItemTarget,
26 resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
28 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, HasModule, Lookup,
29 TraitId, TypeAliasId, VariantId,
31 use hir_expand::name::{name, Name};
32 use itertools::Either;
33 use la_arena::ArenaMap;
34 use rustc_hash::FxHashMap;
35 use stdx::{always, impl_from};
38 db::HirDatabase, fold_tys, fold_tys_and_consts, infer::coerce::CoerceMany,
39 lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Const, DomainGoal,
40 GenericArg, Goal, ImplTraitId, InEnvironment, Interner, ProjectionTy, Substitution,
41 TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt, TyKind,
44 // This lint has a false positive here. See the link below for details.
46 // https://github.com/rust-lang/rust/issues/57411
47 #[allow(unreachable_pub)]
48 pub use coerce::could_coerce;
49 #[allow(unreachable_pub)]
50 pub use unify::could_unify;
59 /// The entry point of type inference.
60 pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
61 let _p = profile::span("infer_query");
62 let resolver = def.resolver(db.upcast());
63 let body = db.body(def);
64 let mut ctx = InferenceContext::new(db, def, &body, resolver);
67 DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)),
68 DefWithBodyId::FunctionId(f) => ctx.collect_fn(f),
69 DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_data(s)),
74 Arc::new(ctx.resolve_all())
77 /// Fully normalize all the types found within `ty` in context of `owner` body definition.
79 /// This is appropriate to use only after type-check: it assumes
80 /// that normalization will succeed, for example.
81 pub(crate) fn normalize(db: &dyn HirDatabase, owner: DefWithBodyId, ty: Ty) -> Ty {
82 if !ty.data(Interner).flags.intersects(TypeFlags::HAS_PROJECTION) {
85 let krate = owner.module(db.upcast()).krate();
88 .map_or_else(|| Arc::new(TraitEnvironment::empty(krate)), |d| db.trait_environment(d));
89 let mut table = unify::InferenceTable::new(db, trait_env);
91 let ty_with_vars = table.normalize_associated_types_in(ty);
92 table.resolve_obligations_as_possible();
93 table.propagate_diverging_flag();
94 table.resolve_completely(ty_with_vars)
97 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
102 impl_from!(ExprId, PatId for ExprOrPatId);
104 /// Binding modes inferred for patterns.
105 /// <https://doc.rust-lang.org/reference/patterns.html#binding-modes>
106 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
107 pub enum BindingMode {
113 fn convert(annotation: BindingAnnotation) -> BindingMode {
115 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move,
116 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Not),
117 BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut),
122 impl Default for BindingMode {
123 fn default() -> Self {
128 /// Used to generalize patterns and assignee expressions.
129 trait PatLike: Into<ExprOrPatId> + Copy {
130 type BindingMode: Copy;
133 this: &mut InferenceContext<'_>,
136 default_bm: Self::BindingMode,
140 impl PatLike for ExprId {
141 type BindingMode = ();
144 this: &mut InferenceContext<'_>,
147 _: Self::BindingMode,
149 this.infer_assignee_expr(id, expected_ty)
153 impl PatLike for PatId {
154 type BindingMode = BindingMode;
157 this: &mut InferenceContext<'_>,
160 default_bm: Self::BindingMode,
162 this.infer_pat(id, expected_ty, default_bm)
167 pub(crate) struct InferOk<T> {
169 goals: Vec<InEnvironment<Goal>>,
173 fn map<U>(self, f: impl FnOnce(T) -> U) -> InferOk<U> {
174 InferOk { value: f(self.value), goals: self.goals }
179 pub(crate) struct TypeError;
180 pub(crate) type InferResult<T> = Result<InferOk<T>, TypeError>;
182 #[derive(Debug, PartialEq, Eq, Clone)]
183 pub enum InferenceDiagnostic {
184 NoSuchField { expr: ExprId },
185 BreakOutsideOfLoop { expr: ExprId, is_break: bool },
186 MismatchedArgCount { call_expr: ExprId, expected: usize, found: usize },
189 /// A mismatch between an expected and an inferred type.
190 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
191 pub struct TypeMismatch {
196 #[derive(Clone, PartialEq, Eq, Debug)]
197 struct InternedStandardTypes {
203 impl Default for InternedStandardTypes {
204 fn default() -> Self {
205 InternedStandardTypes {
206 unknown: TyKind::Error.intern(Interner),
207 bool_: TyKind::Scalar(Scalar::Bool).intern(Interner),
208 unit: TyKind::Tuple(0, Substitution::empty(Interner)).intern(Interner),
212 /// Represents coercing a value to a different type of value.
214 /// We transform values by following a number of `Adjust` steps in order.
215 /// See the documentation on variants of `Adjust` for more details.
217 /// Here are some common scenarios:
219 /// 1. The simplest cases are where a pointer is not adjusted fat vs thin.
220 /// Here the pointer will be dereferenced N times (where a dereference can
221 /// happen to raw or borrowed pointers or any smart pointer which implements
222 /// Deref, including Box<_>). The types of dereferences is given by
223 /// `autoderefs`. It can then be auto-referenced zero or one times, indicated
224 /// by `autoref`, to either a raw or borrowed pointer. In these cases unsize is
227 /// 2. A thin-to-fat coercion involves unsizing the underlying data. We start
228 /// with a thin pointer, deref a number of times, unsize the underlying data,
229 /// then autoref. The 'unsize' phase may change a fixed length array to a
230 /// dynamically sized one, a concrete object to a trait object, or statically
231 /// sized struct to a dynamically sized one. E.g., &[i32; 4] -> &[i32] is
235 /// Deref(None) -> [i32; 4],
236 /// Borrow(AutoBorrow::Ref) -> &[i32; 4],
237 /// Unsize -> &[i32],
240 /// Note that for a struct, the 'deep' unsizing of the struct is not recorded.
241 /// E.g., `struct Foo<T> { x: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>
242 /// The autoderef and -ref are the same as in the above example, but the type
243 /// stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
244 /// the underlying conversions from `[i32; 4]` to `[i32]`.
246 /// 3. Coercing a `Box<T>` to `Box<dyn Trait>` is an interesting special case. In
247 /// that case, we have the pointer we need coming in, so there are no
248 /// autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
249 /// At some point, of course, `Box` should move out of the compiler, in which
250 /// case this is analogous to transforming a struct. E.g., Box<[i32; 4]> ->
251 /// Box<[i32]> is an `Adjust::Unsize` with the target `Box<[i32]>`.
252 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
253 pub struct Adjustment {
258 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
260 /// Go from ! to any type.
262 /// Dereference once, producing a place.
263 Deref(Option<OverloadedDeref>),
264 /// Take the address and produce either a `&` or `*` pointer.
266 Pointer(PointerCast),
269 /// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`
270 /// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.
271 /// The target type is `U` in both cases, with the region and mutability
272 /// being those shared by both the receiver and the returned reference.
273 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
274 pub struct OverloadedDeref(pub Mutability);
276 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
277 pub enum AutoBorrow {
278 /// Converts from T to &T.
280 /// Converts from T to *T.
284 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
285 pub enum PointerCast {
286 /// Go from a fn-item type to a fn-pointer type.
289 /// Go from a safe fn pointer to an unsafe fn pointer.
292 /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
293 /// It cannot convert a closure that requires unsafe.
294 ClosureFnPointer(Safety),
296 /// Go from a mut raw pointer to a const raw pointer.
300 /// Go from `*const [T; N]` to `*const T`
303 /// Unsize a pointer/reference value, e.g., `&[T; n]` to
304 /// `&[T]`. Note that the source could be a thin or fat pointer.
305 /// This will do things like convert thin pointers to fat
306 /// pointers, or convert structs containing thin pointers to
307 /// structs containing fat pointers, or convert between fat
308 /// pointers. We don't store the details of how the transform is
309 /// done (in fact, we don't know that, because it might depend on
310 /// the precise type parameters). We just store the target
311 /// type. Codegen backends and miri figure out what has to be done
312 /// based on the precise source/target type at hand.
316 /// The result of type inference: A mapping from expressions and patterns to types.
317 #[derive(Clone, PartialEq, Eq, Debug, Default)]
318 pub struct InferenceResult {
319 /// For each method call expr, records the function it resolves to.
320 method_resolutions: FxHashMap<ExprId, (FunctionId, Substitution)>,
321 /// For each field access expr, records the field it resolves to.
322 field_resolutions: FxHashMap<ExprId, FieldId>,
323 /// For each struct literal or pattern, records the variant it resolves to.
324 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,
325 /// For each associated item record what it resolves to
326 assoc_resolutions: FxHashMap<ExprOrPatId, AssocItemId>,
327 pub diagnostics: Vec<InferenceDiagnostic>,
328 pub type_of_expr: ArenaMap<ExprId, Ty>,
329 /// For each pattern record the type it resolves to.
331 /// **Note**: When a pattern type is resolved it may still contain
332 /// unresolved or missing subpatterns or subpatterns of mismatched types.
333 pub type_of_pat: ArenaMap<PatId, Ty>,
334 type_mismatches: FxHashMap<ExprOrPatId, TypeMismatch>,
335 /// Interned Unknown to return references to.
336 standard_types: InternedStandardTypes,
337 /// Stores the types which were implicitly dereferenced in pattern binding modes.
338 pub pat_adjustments: FxHashMap<PatId, Vec<Ty>>,
339 pub pat_binding_modes: FxHashMap<PatId, BindingMode>,
340 pub expr_adjustments: FxHashMap<ExprId, Vec<Adjustment>>,
343 impl InferenceResult {
344 pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, Substitution)> {
345 self.method_resolutions.get(&expr).cloned()
347 pub fn field_resolution(&self, expr: ExprId) -> Option<FieldId> {
348 self.field_resolutions.get(&expr).copied()
350 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {
351 self.variant_resolutions.get(&id.into()).copied()
353 pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> {
354 self.variant_resolutions.get(&id.into()).copied()
356 pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<AssocItemId> {
357 self.assoc_resolutions.get(&id.into()).copied()
359 pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<AssocItemId> {
360 self.assoc_resolutions.get(&id.into()).copied()
362 pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> {
363 self.type_mismatches.get(&expr.into())
365 pub fn type_mismatch_for_pat(&self, pat: PatId) -> Option<&TypeMismatch> {
366 self.type_mismatches.get(&pat.into())
368 pub fn expr_type_mismatches(&self) -> impl Iterator<Item = (ExprId, &TypeMismatch)> {
369 self.type_mismatches.iter().filter_map(|(expr_or_pat, mismatch)| match *expr_or_pat {
370 ExprOrPatId::ExprId(expr) => Some((expr, mismatch)),
374 pub fn pat_type_mismatches(&self) -> impl Iterator<Item = (PatId, &TypeMismatch)> {
375 self.type_mismatches.iter().filter_map(|(expr_or_pat, mismatch)| match *expr_or_pat {
376 ExprOrPatId::PatId(pat) => Some((pat, mismatch)),
382 impl Index<ExprId> for InferenceResult {
385 fn index(&self, expr: ExprId) -> &Ty {
386 self.type_of_expr.get(expr).unwrap_or(&self.standard_types.unknown)
390 impl Index<PatId> for InferenceResult {
393 fn index(&self, pat: PatId) -> &Ty {
394 self.type_of_pat.get(pat).unwrap_or(&self.standard_types.unknown)
398 /// The inference context contains all information needed during type inference.
399 #[derive(Clone, Debug)]
400 pub(crate) struct InferenceContext<'a> {
401 pub(crate) db: &'a dyn HirDatabase,
402 pub(crate) owner: DefWithBodyId,
403 pub(crate) body: &'a Body,
404 pub(crate) resolver: Resolver,
405 table: unify::InferenceTable<'a>,
406 trait_env: Arc<TraitEnvironment>,
407 pub(crate) result: InferenceResult,
408 /// The return type of the function being inferred, the closure or async block if we're
409 /// currently within one.
411 /// We might consider using a nested inference context for checking
412 /// closures, but currently this is the only field that will change there,
413 /// so it doesn't make sense.
416 breakables: Vec<BreakableContext>,
419 #[derive(Clone, Debug)]
420 struct BreakableContext {
421 /// Whether this context contains at least one break expression.
423 /// The coercion target of the context.
425 /// The optional label of the context.
426 label: Option<name::Name>,
430 #[derive(Clone, Debug)]
434 /// A border is something like an async block, closure etc. Anything that prevents
435 /// breaking/continuing through
439 fn find_breakable<'c>(
440 ctxs: &'c mut [BreakableContext],
441 label: Option<&name::Name>,
442 ) -> Option<&'c mut BreakableContext> {
446 .take_while(|it| matches!(it.kind, BreakableKind::Block | BreakableKind::Loop));
448 Some(_) => ctxs.find(|ctx| ctx.label.as_ref() == label),
449 None => ctxs.find(|ctx| matches!(ctx.kind, BreakableKind::Loop)),
453 fn find_continuable<'c>(
454 ctxs: &'c mut [BreakableContext],
455 label: Option<&name::Name>,
456 ) -> Option<&'c mut BreakableContext> {
458 Some(_) => find_breakable(ctxs, label).filter(|it| matches!(it.kind, BreakableKind::Loop)),
459 None => find_breakable(ctxs, label),
463 impl<'a> InferenceContext<'a> {
465 db: &'a dyn HirDatabase,
466 owner: DefWithBodyId,
470 let krate = owner.module(db.upcast()).krate();
471 let trait_env = owner
473 .map_or_else(|| Arc::new(TraitEnvironment::empty(krate)), |d| db.trait_environment(d));
475 result: InferenceResult::default(),
476 table: unify::InferenceTable::new(db, trait_env.clone()),
478 return_ty: TyKind::Error.intern(Interner), // set in collect_fn_signature
483 diverges: Diverges::Maybe,
484 breakables: Vec::new(),
488 fn resolve_all(self) -> InferenceResult {
489 let InferenceContext { mut table, mut result, .. } = self;
491 // FIXME resolve obligations as well (use Guidance if necessary)
492 table.resolve_obligations_as_possible();
494 // make sure diverging type variables are marked as such
495 table.propagate_diverging_flag();
496 for ty in result.type_of_expr.values_mut() {
497 *ty = table.resolve_completely(ty.clone());
499 for ty in result.type_of_pat.values_mut() {
500 *ty = table.resolve_completely(ty.clone());
502 for mismatch in result.type_mismatches.values_mut() {
503 mismatch.expected = table.resolve_completely(mismatch.expected.clone());
504 mismatch.actual = table.resolve_completely(mismatch.actual.clone());
506 for (_, subst) in result.method_resolutions.values_mut() {
507 *subst = table.resolve_completely(subst.clone());
509 for adjustment in result.expr_adjustments.values_mut().flatten() {
510 adjustment.target = table.resolve_completely(adjustment.target.clone());
512 for adjustment in result.pat_adjustments.values_mut().flatten() {
513 *adjustment = table.resolve_completely(adjustment.clone());
518 fn collect_const(&mut self, data: &ConstData) {
519 self.return_ty = self.make_ty(&data.type_ref);
522 fn collect_static(&mut self, data: &StaticData) {
523 self.return_ty = self.make_ty(&data.type_ref);
526 fn collect_fn(&mut self, func: FunctionId) {
527 let data = self.db.function_data(func);
528 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
529 .with_impl_trait_mode(ImplTraitLoweringMode::Param);
531 data.params.iter().map(|(_, type_ref)| ctx.lower_ty(type_ref)).collect::<Vec<_>>();
532 for (ty, pat) in param_tys.into_iter().zip(self.body.params.iter()) {
533 let ty = self.insert_type_vars(ty);
534 let ty = self.normalize_associated_types_in(ty);
536 self.infer_pat(*pat, &ty, BindingMode::default());
538 let error_ty = &TypeRef::Error;
539 let return_ty = if data.has_async_kw() {
540 data.async_ret_type.as_deref().unwrap_or(error_ty)
544 let return_ty = self.make_ty_with_mode(return_ty, ImplTraitLoweringMode::Opaque);
545 self.return_ty = return_ty;
547 if let Some(rpits) = self.db.return_type_impl_traits(func) {
548 // RPIT opaque types use substitution of their parent function.
549 let fn_placeholders = TyBuilder::placeholder_subst(self.db, func);
550 self.return_ty = fold_tys(
551 self.return_ty.clone(),
553 let opaque_ty_id = match ty.kind(Interner) {
554 TyKind::OpaqueType(opaque_ty_id, _) => *opaque_ty_id,
557 let idx = match self.db.lookup_intern_impl_trait_id(opaque_ty_id.into()) {
558 ImplTraitId::ReturnTypeImplTrait(_, idx) => idx,
561 let bounds = (*rpits).map_ref(|rpits| {
562 rpits.impl_traits[idx as usize].bounds.map_ref(|it| it.into_iter())
564 let var = self.table.new_type_var();
565 let var_subst = Substitution::from1(Interner, var.clone());
566 for bound in bounds {
568 bound.map(|it| it.cloned()).substitute(Interner, &fn_placeholders);
569 let (var_predicate, binders) = predicate
570 .substitute(Interner, &var_subst)
571 .into_value_and_skipped_binders();
572 always!(binders.len(Interner) == 0); // quantified where clauses not yet handled
573 self.push_obligation(var_predicate.cast(Interner));
577 DebruijnIndex::INNERMOST,
582 fn infer_body(&mut self) {
583 self.infer_expr_coerce(self.body.body_expr, &Expectation::has_type(self.return_ty.clone()));
586 fn write_expr_ty(&mut self, expr: ExprId, ty: Ty) {
587 self.result.type_of_expr.insert(expr, ty);
590 fn write_expr_adj(&mut self, expr: ExprId, adjustments: Vec<Adjustment>) {
591 self.result.expr_adjustments.insert(expr, adjustments);
594 fn write_method_resolution(&mut self, expr: ExprId, func: FunctionId, subst: Substitution) {
595 self.result.method_resolutions.insert(expr, (func, subst));
598 fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId) {
599 self.result.variant_resolutions.insert(id, variant);
602 fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItemId) {
603 self.result.assoc_resolutions.insert(id, item);
606 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) {
607 self.result.type_of_pat.insert(pat, ty);
610 fn push_diagnostic(&mut self, diagnostic: InferenceDiagnostic) {
611 self.result.diagnostics.push(diagnostic);
614 fn make_ty_with_mode(
617 impl_trait_mode: ImplTraitLoweringMode,
619 // FIXME use right resolver for block
620 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
621 .with_impl_trait_mode(impl_trait_mode);
622 let ty = ctx.lower_ty(type_ref);
623 let ty = self.insert_type_vars(ty);
624 self.normalize_associated_types_in(ty)
627 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
628 self.make_ty_with_mode(type_ref, ImplTraitLoweringMode::Disallowed)
631 fn err_ty(&self) -> Ty {
632 self.result.standard_types.unknown.clone()
635 /// Replaces ConstScalar::Unknown by a new type var, so we can maybe still infer it.
636 fn insert_const_vars_shallow(&mut self, c: Const) -> Const {
637 let data = c.data(Interner);
639 ConstValue::Concrete(cc) => match cc.interned {
640 hir_def::type_ref::ConstScalar::Unknown => {
641 self.table.new_const_var(data.ty.clone())
649 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it.
650 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
651 match ty.kind(Interner) {
652 TyKind::Error => self.table.new_type_var(),
653 TyKind::InferenceVar(..) => {
654 let ty_resolved = self.resolve_ty_shallow(&ty);
655 if ty_resolved.is_unknown() {
656 self.table.new_type_var()
665 fn insert_type_vars(&mut self, ty: Ty) -> Ty {
669 Either::Left(ty) => Either::Left(self.insert_type_vars_shallow(ty)),
670 Either::Right(c) => Either::Right(self.insert_const_vars_shallow(c)),
672 DebruijnIndex::INNERMOST,
676 fn push_obligation(&mut self, o: DomainGoal) {
677 self.table.register_obligation(o.cast(Interner));
680 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
681 self.table.unify(ty1, ty2)
684 /// Recurses through the given type, normalizing associated types mentioned
685 /// in it by replacing them by type variables and registering obligations to
686 /// resolve later. This should be done once for every type we get from some
687 /// type annotation (e.g. from a let type annotation, field type or function
688 /// call). `make_ty` handles this already, but e.g. for field types we need
689 /// to do it as well.
690 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
691 self.table.normalize_associated_types_in(ty)
694 fn resolve_ty_shallow(&mut self, ty: &Ty) -> Ty {
695 self.table.resolve_ty_shallow(ty)
698 fn resolve_associated_type(&mut self, inner_ty: Ty, assoc_ty: Option<TypeAliasId>) -> Ty {
699 self.resolve_associated_type_with_params(inner_ty, assoc_ty, &[])
702 fn resolve_associated_type_with_params(
705 assoc_ty: Option<TypeAliasId>,
706 params: &[GenericArg],
709 Some(res_assoc_ty) => {
710 let trait_ = match res_assoc_ty.lookup(self.db.upcast()).container {
711 hir_def::ItemContainerId::TraitId(trait_) => trait_,
712 _ => panic!("resolve_associated_type called with non-associated type"),
714 let ty = self.table.new_type_var();
715 let mut param_iter = params.iter().cloned();
716 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
718 .fill(|_| param_iter.next().unwrap())
720 let alias_eq = AliasEq {
721 alias: AliasTy::Projection(ProjectionTy {
722 associated_ty_id: to_assoc_type_id(res_assoc_ty),
723 substitution: trait_ref.substitution.clone(),
727 self.push_obligation(trait_ref.cast(Interner));
728 self.push_obligation(alias_eq.cast(Interner));
731 None => self.err_ty(),
735 fn resolve_variant(&mut self, path: Option<&Path>, value_ns: bool) -> (Ty, Option<VariantId>) {
736 let path = match path {
738 None => return (self.err_ty(), None),
740 let resolver = &self.resolver;
741 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
742 // FIXME: this should resolve assoc items as well, see this example:
743 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521
744 let (resolution, unresolved) = if value_ns {
745 match resolver.resolve_path_in_value_ns(self.db.upcast(), path.mod_path()) {
746 Some(ResolveValueResult::ValueNs(value)) => match value {
747 ValueNs::EnumVariantId(var) => {
748 let substs = ctx.substs_from_path(path, var.into(), true);
749 let ty = self.db.ty(var.parent.into());
750 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
751 return (ty, Some(var.into()));
753 ValueNs::StructId(strukt) => {
754 let substs = ctx.substs_from_path(path, strukt.into(), true);
755 let ty = self.db.ty(strukt.into());
756 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
757 return (ty, Some(strukt.into()));
759 ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
760 _ => return (self.err_ty(), None),
762 Some(ResolveValueResult::Partial(typens, unresolved)) => (typens, Some(unresolved)),
763 None => return (self.err_ty(), None),
766 match resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
768 None => return (self.err_ty(), None),
771 return match resolution {
772 TypeNs::AdtId(AdtId::StructId(strukt)) => {
773 let substs = ctx.substs_from_path(path, strukt.into(), true);
774 let ty = self.db.ty(strukt.into());
775 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
776 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
778 TypeNs::AdtId(AdtId::UnionId(u)) => {
779 let substs = ctx.substs_from_path(path, u.into(), true);
780 let ty = self.db.ty(u.into());
781 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
782 forbid_unresolved_segments((ty, Some(u.into())), unresolved)
784 TypeNs::EnumVariantId(var) => {
785 let substs = ctx.substs_from_path(path, var.into(), true);
786 let ty = self.db.ty(var.parent.into());
787 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
788 forbid_unresolved_segments((ty, Some(var.into())), unresolved)
790 TypeNs::SelfType(impl_id) => {
791 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
792 let substs = generics.placeholder_subst(self.db);
793 let ty = self.db.impl_self_ty(impl_id).substitute(Interner, &substs);
794 self.resolve_variant_on_alias(ty, unresolved, path)
796 TypeNs::TypeAliasId(it) => {
797 let ty = TyBuilder::def_ty(self.db, it.into())
798 .fill_with_inference_vars(&mut self.table)
800 self.resolve_variant_on_alias(ty, unresolved, path)
802 TypeNs::AdtSelfType(_) => {
803 // FIXME this could happen in array size expressions, once we're checking them
804 (self.err_ty(), None)
806 TypeNs::GenericParam(_) => {
807 // FIXME potentially resolve assoc type
808 (self.err_ty(), None)
810 TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => {
812 (self.err_ty(), None)
816 fn forbid_unresolved_segments(
817 result: (Ty, Option<VariantId>),
818 unresolved: Option<usize>,
819 ) -> (Ty, Option<VariantId>) {
820 if unresolved.is_none() {
824 (TyKind::Error.intern(Interner), None)
829 fn resolve_variant_on_alias(
832 unresolved: Option<usize>,
834 ) -> (Ty, Option<VariantId>) {
835 let remaining = unresolved.map(|x| path.segments().skip(x).len()).filter(|x| x > &0);
838 let variant = ty.as_adt().and_then(|(adt_id, _)| match adt_id {
839 AdtId::StructId(s) => Some(VariantId::StructId(s)),
840 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
841 AdtId::EnumId(_) => {
842 // FIXME Error E0071, expected struct, variant or union type, found enum `Foo`
849 let segment = path.mod_path().segments().last().unwrap();
850 // this could be an enum variant or associated type
851 if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
852 let enum_data = self.db.enum_data(enum_id);
853 if let Some(local_id) = enum_data.variant(segment) {
854 let variant = EnumVariantId { parent: enum_id, local_id };
855 return (ty, Some(variant.into()));
858 // FIXME potentially resolve assoc type
859 (self.err_ty(), None)
863 (self.err_ty(), None)
868 fn resolve_lang_item(&self, name: Name) -> Option<LangItemTarget> {
869 let krate = self.resolver.krate();
870 self.db.lang_item(krate, name.to_smol_str())
873 fn resolve_into_iter_item(&self) -> Option<TypeAliasId> {
874 let path = path![core::iter::IntoIterator];
875 let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
876 self.db.trait_data(trait_).associated_type_by_name(&name![Item])
879 fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> {
880 // FIXME resolve via lang_item once try v2 is stable
881 let path = path![core::ops::Try];
882 let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
883 let trait_data = self.db.trait_data(trait_);
885 // FIXME remove once try v2 is stable
886 .associated_type_by_name(&name![Ok])
887 .or_else(|| trait_data.associated_type_by_name(&name![Output]))
890 fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> {
891 let trait_ = self.resolve_lang_item(name![neg])?.as_trait()?;
892 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
895 fn resolve_ops_not_output(&self) -> Option<TypeAliasId> {
896 let trait_ = self.resolve_lang_item(name![not])?.as_trait()?;
897 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
900 fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
903 .resolve_known_trait(self.db.upcast(), &path![core::future::IntoFuture])
904 .or_else(|| self.resolve_lang_item(name![future_trait])?.as_trait())?;
905 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
908 fn resolve_boxed_box(&self) -> Option<AdtId> {
909 let struct_ = self.resolve_lang_item(name![owned_box])?.as_struct()?;
913 fn resolve_range_full(&self) -> Option<AdtId> {
914 let path = path![core::ops::RangeFull];
915 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
919 fn resolve_range(&self) -> Option<AdtId> {
920 let path = path![core::ops::Range];
921 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
925 fn resolve_range_inclusive(&self) -> Option<AdtId> {
926 let path = path![core::ops::RangeInclusive];
927 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
931 fn resolve_range_from(&self) -> Option<AdtId> {
932 let path = path![core::ops::RangeFrom];
933 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
937 fn resolve_range_to(&self) -> Option<AdtId> {
938 let path = path![core::ops::RangeTo];
939 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
943 fn resolve_range_to_inclusive(&self) -> Option<AdtId> {
944 let path = path![core::ops::RangeToInclusive];
945 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
949 fn resolve_ops_index(&self) -> Option<TraitId> {
950 self.resolve_lang_item(name![index])?.as_trait()
953 fn resolve_ops_index_output(&self) -> Option<TypeAliasId> {
954 let trait_ = self.resolve_ops_index()?;
955 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
959 /// When inferring an expression, we propagate downward whatever type hint we
960 /// are able in the form of an `Expectation`.
961 #[derive(Clone, PartialEq, Eq, Debug)]
962 pub(crate) enum Expectation {
965 // Castable(Ty), // rustc has this, we currently just don't propagate an expectation for casts
966 RValueLikeUnsized(Ty),
970 /// The expectation that the type of the expression needs to equal the given
972 fn has_type(ty: Ty) -> Self {
974 // FIXME: get rid of this?
977 Expectation::HasType(ty)
981 fn from_option(ty: Option<Ty>) -> Self {
982 ty.map_or(Expectation::None, Expectation::HasType)
985 /// The following explanation is copied straight from rustc:
986 /// Provides an expectation for an rvalue expression given an *optional*
987 /// hint, which is not required for type safety (the resulting type might
988 /// be checked higher up, as is the case with `&expr` and `box expr`), but
989 /// is useful in determining the concrete type.
991 /// The primary use case is where the expected type is a fat pointer,
992 /// like `&[isize]`. For example, consider the following statement:
994 /// let x: &[isize] = &[1, 2, 3];
996 /// In this case, the expected type for the `&[1, 2, 3]` expression is
997 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
998 /// expectation `ExpectHasType([isize])`, that would be too strong --
999 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
1000 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
1001 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
1002 /// which still is useful, because it informs integer literals and the like.
1003 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
1004 /// for examples of where this comes up,.
1005 fn rvalue_hint(table: &mut unify::InferenceTable<'_>, ty: Ty) -> Self {
1006 // FIXME: do struct_tail_without_normalization
1007 match table.resolve_ty_shallow(&ty).kind(Interner) {
1008 TyKind::Slice(_) | TyKind::Str | TyKind::Dyn(_) => Expectation::RValueLikeUnsized(ty),
1009 _ => Expectation::has_type(ty),
1013 /// This expresses no expectation on the type.
1018 fn resolve(&self, table: &mut unify::InferenceTable<'_>) -> Expectation {
1020 Expectation::None => Expectation::None,
1021 Expectation::HasType(t) => Expectation::HasType(table.resolve_ty_shallow(t)),
1022 Expectation::RValueLikeUnsized(t) => {
1023 Expectation::RValueLikeUnsized(table.resolve_ty_shallow(t))
1028 fn to_option(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
1029 match self.resolve(table) {
1030 Expectation::None => None,
1031 Expectation::HasType(t) |
1032 // Expectation::Castable(t) |
1033 Expectation::RValueLikeUnsized(t) => Some(t),
1037 fn only_has_type(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
1039 Expectation::HasType(t) => Some(table.resolve_ty_shallow(t)),
1040 // Expectation::Castable(_) |
1041 Expectation::RValueLikeUnsized(_) | Expectation::None => None,
1045 /// Comment copied from rustc:
1046 /// Disregard "castable to" expectations because they
1047 /// can lead us astray. Consider for example `if cond
1048 /// {22} else {c} as u8` -- if we propagate the
1049 /// "castable to u8" constraint to 22, it will pick the
1050 /// type 22u8, which is overly constrained (c might not
1051 /// be a u8). In effect, the problem is that the
1052 /// "castable to" expectation is not the tightest thing
1053 /// we can say, so we want to drop it in this case.
1054 /// The tightest thing we can say is "must unify with
1055 /// else branch". Note that in the case of a "has type"
1056 /// constraint, this limitation does not hold.
1058 /// If the expected type is just a type variable, then don't use
1059 /// an expected type. Otherwise, we might write parts of the type
1060 /// when checking the 'then' block which are incompatible with the
1062 fn adjust_for_branches(&self, table: &mut unify::InferenceTable<'_>) -> Expectation {
1064 Expectation::HasType(ety) => {
1065 let ety = table.resolve_ty_shallow(ety);
1066 if !ety.is_ty_var() {
1067 Expectation::HasType(ety)
1072 Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety.clone()),
1073 _ => Expectation::None,
1078 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
1085 fn is_always(self) -> bool {
1086 self == Diverges::Always
1090 impl std::ops::BitAnd for Diverges {
1092 fn bitand(self, other: Self) -> Self {
1093 std::cmp::min(self, other)
1097 impl std::ops::BitOr for Diverges {
1099 fn bitor(self, other: Self) -> Self {
1100 std::cmp::max(self, other)
1104 impl std::ops::BitAndAssign for Diverges {
1105 fn bitand_assign(&mut self, other: Self) {
1106 *self = *self & other;
1110 impl std::ops::BitOrAssign for Diverges {
1111 fn bitor_assign(&mut self, other: Self) {
1112 *self = *self | other;