about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src/traits
diff options
context:
space:
mode:
authorBoxy <supbscripter@gmail.com>2022-11-15 22:53:30 +0000
committerkadmin <julianknodt@gmail.com>2022-11-25 09:28:43 +0000
commit0ae3c5c60964bdfb95a524e86d7804e97ca6ceb8 (patch)
tree25bf3c72b3da6124047415047165423376488d36 /compiler/rustc_trait_selection/src/traits
parentd75cd5c05111256a3c0d82d0df727cb2b52680b7 (diff)
downloadrust-0ae3c5c60964bdfb95a524e86d7804e97ca6ceb8.tar.gz
rust-0ae3c5c60964bdfb95a524e86d7804e97ca6ceb8.zip
handle assoc consts in fulfill `ConstEquate`
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits')
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs50
1 files changed, 27 insertions, 23 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 806e031a4bb..1fd0926fec9 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -457,41 +457,45 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                         tcx.features().generic_const_exprs,
                         "`ConstEquate` without a feature gate: {c1:?} {c2:?}",
                     );
-                    debug!(?c1, ?c2, "equating consts");
                     // FIXME: we probably should only try to unify abstract constants
                     // if the constants depend on generic parameters.
                     //
                     // Let's just see where this breaks :shrug:
-                    match (c1.kind(), c2.kind()) {
-                        (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) => {
-                            // FIXME: remove
-                            use rustc_hir::def::DefKind;
-                            if tcx.def_kind(a.def.did) == DefKind::AssocConst
-                                || tcx.def_kind(b.def.did) == DefKind::AssocConst
+                    {
+                        let c1 =
+                            if let Ok(Some(a)) = tcx.expand_abstract_consts(c1) { a } else { c1 };
+                        let c2 =
+                            if let Ok(Some(b)) = tcx.expand_abstract_consts(c2) { b } else { c2 };
+                        debug!("equating consts:\nc1= {:?}\nc2= {:?}", c1, c2);
+
+                        use rustc_hir::def::DefKind;
+                        use ty::ConstKind::Unevaluated;
+                        match (c1.kind(), c2.kind()) {
+                            (Unevaluated(a), Unevaluated(b))
+                                if a.def.did == b.def.did
+                                    && tcx.def_kind(a.def.did) == DefKind::AssocConst =>
                             {
-                                // Two different constants using generic parameters ~> error.
-                                let expected_found = ExpectedFound::new(true, c1, c2);
-                                return ProcessResult::Error(
-                                    FulfillmentErrorCode::CodeConstEquateError(
-                                        expected_found,
-                                        TypeError::ConstMismatch(expected_found),
-                                    ),
-                                );
-                            }
-
-                            if let Ok(Some(a)) = tcx.expand_abstract_consts(c1)
-                                && let Ok(Some(b)) = tcx.expand_abstract_consts(c2)
-                                && a.ty() == b.ty() 
-                                && let Ok(new_obligations) = infcx
+                                if let Ok(new_obligations) = infcx
                                     .at(&obligation.cause, obligation.param_env)
-                                    .eq(a, b) 
+                                    .trace(c1, c2)
+                                    .eq(a.substs, b.substs)
                                 {
                                     return ProcessResult::Changed(mk_pending(
                                         new_obligations.into_obligations(),
                                     ));
                                 }
+                            }
+                            (_, Unevaluated(_)) | (Unevaluated(_), _) => (),
+                            (_, _) => {
+                                if let Ok(new_obligations) =
+                                    infcx.at(&obligation.cause, obligation.param_env).eq(c1, c2)
+                                {
+                                    return ProcessResult::Changed(mk_pending(
+                                        new_obligations.into_obligations(),
+                                    ));
+                                }
+                            }
                         }
-                        _ => {}
                     }
 
                     let stalled_on = &mut pending_obligation.stalled_on;