]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir-ty/src/infer.rs
Auto merge of #13056 - DropDemBits:make-refactors, r=Veykril
[rust.git] / crates / hir-ty / src / infer.rs
index a19ff8bf60168cbf6db3302e7488674355c310be..5df48e5fdcbaf40502d0aa11f3b9bd666132b771 100644 (file)
@@ -125,6 +125,44 @@ fn default() -> Self {
     }
 }
 
+/// Used to generalize patterns and assignee expressions.
+trait PatLike: Into<ExprOrPatId> + Copy {
+    type BindingMode: Copy;
+
+    fn infer(
+        this: &mut InferenceContext<'_>,
+        id: Self,
+        expected_ty: &Ty,
+        default_bm: Self::BindingMode,
+    ) -> Ty;
+}
+
+impl PatLike for ExprId {
+    type BindingMode = ();
+
+    fn infer(
+        this: &mut InferenceContext<'_>,
+        id: Self,
+        expected_ty: &Ty,
+        _: Self::BindingMode,
+    ) -> Ty {
+        this.infer_assignee_expr(id, expected_ty)
+    }
+}
+
+impl PatLike for PatId {
+    type BindingMode = BindingMode;
+
+    fn infer(
+        this: &mut InferenceContext<'_>,
+        id: Self,
+        expected_ty: &Ty,
+        default_bm: Self::BindingMode,
+    ) -> Ty {
+        this.infer_pat(id, expected_ty, default_bm)
+    }
+}
+
 #[derive(Debug)]
 pub(crate) struct InferOk<T> {
     value: T,
@@ -572,10 +610,10 @@ fn insert_const_vars_shallow(&mut self, c: Const) -> Const {
         let data = c.data(Interner);
         match data.value {
             ConstValue::Concrete(cc) => match cc.interned {
-                hir_def::type_ref::ConstScalar::Usize(_) => c,
                 hir_def::type_ref::ConstScalar::Unknown => {
                     self.table.new_const_var(data.ty.clone())
                 }
+                _ => c,
             },
             _ => c,
         }
@@ -696,6 +734,7 @@ fn resolve_variant(&mut self, path: Option<&Path>, value_ns: bool) -> (Ty, Optio
                         let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
                         return (ty, Some(strukt.into()));
                     }
+                    ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
                     _ => return (self.err_ty(), None),
                 },
                 Some(ResolveValueResult::Partial(typens, unresolved)) => (typens, Some(unresolved)),
@@ -837,7 +876,10 @@ fn resolve_ops_not_output(&self) -> Option<TypeAliasId> {
     }
 
     fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
-        let trait_ = self.resolve_lang_item(name![future_trait])?.as_trait()?;
+        let trait_ = self
+            .resolver
+            .resolve_known_trait(self.db.upcast(), &path![core::future::IntoFuture])
+            .or_else(|| self.resolve_lang_item(name![future_trait])?.as_trait())?;
         self.db.trait_data(trait_).associated_type_by_name(&name![Output])
     }
 
@@ -938,7 +980,7 @@ fn from_option(ty: Option<Ty>) -> Self {
     /// which still is useful, because it informs integer literals and the like.
     /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
     /// for examples of where this comes up,.
-    fn rvalue_hint(table: &mut unify::InferenceTable, ty: Ty) -> Self {
+    fn rvalue_hint(table: &mut unify::InferenceTable<'_>, ty: Ty) -> Self {
         // FIXME: do struct_tail_without_normalization
         match table.resolve_ty_shallow(&ty).kind(Interner) {
             TyKind::Slice(_) | TyKind::Str | TyKind::Dyn(_) => Expectation::RValueLikeUnsized(ty),
@@ -951,7 +993,7 @@ fn none() -> Self {
         Expectation::None
     }
 
-    fn resolve(&self, table: &mut unify::InferenceTable) -> Expectation {
+    fn resolve(&self, table: &mut unify::InferenceTable<'_>) -> Expectation {
         match self {
             Expectation::None => Expectation::None,
             Expectation::HasType(t) => Expectation::HasType(table.resolve_ty_shallow(t)),
@@ -961,7 +1003,7 @@ fn resolve(&self, table: &mut unify::InferenceTable) -> Expectation {
         }
     }
 
-    fn to_option(&self, table: &mut unify::InferenceTable) -> Option<Ty> {
+    fn to_option(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
         match self.resolve(table) {
             Expectation::None => None,
             Expectation::HasType(t) |
@@ -970,7 +1012,7 @@ fn to_option(&self, table: &mut unify::InferenceTable) -> Option<Ty> {
         }
     }
 
-    fn only_has_type(&self, table: &mut unify::InferenceTable) -> Option<Ty> {
+    fn only_has_type(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
         match self {
             Expectation::HasType(t) => Some(table.resolve_ty_shallow(t)),
             // Expectation::Castable(_) |
@@ -995,7 +1037,7 @@ fn only_has_type(&self, table: &mut unify::InferenceTable) -> Option<Ty> {
     /// an expected type. Otherwise, we might write parts of the type
     /// when checking the 'then' block which are incompatible with the
     /// 'else' branch.
-    fn adjust_for_branches(&self, table: &mut unify::InferenceTable) -> Expectation {
+    fn adjust_for_branches(&self, table: &mut unify::InferenceTable<'_>) -> Expectation {
         match self {
             Expectation::HasType(ety) => {
                 let ety = table.resolve_ty_shallow(ety);