about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-07-21 15:45:35 +0000
committerMichael Goulet <michael@errs.io>2022-07-21 15:45:35 +0000
commitcd89978d869587fc025286b0326116819d5b78e4 (patch)
tree77a3750e9700b47311593eb63396cdf3da7bae59
parent8926dac54911e9382763876dc3a8e7a4ae50e270 (diff)
downloadrust-cd89978d869587fc025286b0326116819d5b78e4.tar.gz
rust-cd89978d869587fc025286b0326116819d5b78e4.zip
Generalize same_type_modulo_infer
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs37
-rw-r--r--src/test/ui/issues/issue-59494.stderr2
2 files changed, 34 insertions, 5 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 5c1ab2bf588..93f94bd497a 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2670,8 +2670,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     /// Float types, respectively). When comparing two ADTs, these rules apply recursively.
     pub fn same_type_modulo_infer(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
         let (a, b) = self.resolve_vars_if_possible((a, b));
-        match (&a.kind(), &b.kind()) {
-            (&ty::Adt(did_a, substs_a), &ty::Adt(did_b, substs_b)) => {
+        match (a.kind(), b.kind()) {
+            (&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b)) => {
+                if def_a != def_b {
+                    return false;
+                }
+
+                substs_a
+                    .types()
+                    .zip(substs_b.types())
+                    .all(|(a, b)| self.same_type_modulo_infer(a, b))
+            }
+            (&ty::FnDef(did_a, substs_a), &ty::FnDef(did_b, substs_b)) => {
                 if did_a != did_b {
                     return false;
                 }
@@ -2694,7 +2704,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             | (&ty::Infer(ty::InferTy::TyVar(_)), _)
             | (_, &ty::Infer(ty::InferTy::TyVar(_))) => true,
             (&ty::Ref(_, ty_a, mut_a), &ty::Ref(_, ty_b, mut_b)) => {
-                mut_a == mut_b && self.same_type_modulo_infer(*ty_a, *ty_b)
+                mut_a == mut_b && self.same_type_modulo_infer(ty_a, ty_b)
+            }
+            (&ty::RawPtr(a), &ty::RawPtr(b)) => {
+                a.mutbl == b.mutbl && self.same_type_modulo_infer(a.ty, b.ty)
+            }
+            (&ty::Slice(a), &ty::Slice(b)) => self.same_type_modulo_infer(a, b),
+            (&ty::Array(a_ty, a_ct), &ty::Array(b_ty, b_ct)) => {
+                self.same_type_modulo_infer(a_ty, b_ty) && a_ct == b_ct
+            }
+            (&ty::Tuple(a), &ty::Tuple(b)) => {
+                if a.len() != b.len() {
+                    return false;
+                }
+                std::iter::zip(a.iter(), b.iter()).all(|(a, b)| self.same_type_modulo_infer(a, b))
+            }
+            (&ty::FnPtr(a), &ty::FnPtr(b)) => {
+                let a = a.skip_binder().inputs_and_output;
+                let b = b.skip_binder().inputs_and_output;
+                if a.len() != b.len() {
+                    return false;
+                }
+                std::iter::zip(a.iter(), b.iter()).all(|(a, b)| self.same_type_modulo_infer(a, b))
             }
             // FIXME(compiler-errors): This needs to be generalized more
             _ => a == b,
diff --git a/src/test/ui/issues/issue-59494.stderr b/src/test/ui/issues/issue-59494.stderr
index 8b542bb69de..a9284535e4d 100644
--- a/src/test/ui/issues/issue-59494.stderr
+++ b/src/test/ui/issues/issue-59494.stderr
@@ -7,8 +7,6 @@ LL |     let t8 = t8n(t7, t7p(f, g));
    |              required by a bound introduced by this call
    |
    = help: the trait `Fn<(_,)>` is not implemented for `impl Fn(((_, _), _))`
-   = note: expected a closure with arguments `(((_, _), _),)`
-              found a closure with arguments `(_,)`
 note: required by a bound in `t8n`
   --> $DIR/issue-59494.rs:5:45
    |