]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
do use ty::Const in patterns and abstract consts
[rust.git] / compiler / rustc_trait_selection / src / traits / const_evaluatable.rs
index d114515eca1564a8a3f96ea70cb5fe076546335f..709dd346efcc5203ce4f68996a29af983e3f3ecf 100644 (file)
@@ -376,6 +376,14 @@ fn visit_pat(&mut self, pat: &thir::Pat<'tcx>) {
                     visit::walk_pat(self, pat);
                 }
             }
+
+            fn visit_const(&mut self, ct: ty::Const<'tcx>) {
+                self.is_poly |= ct.has_param_types_or_consts();
+            }
+
+            fn visit_constant(&mut self, ct: mir::ConstantKind<'tcx>) {
+                self.is_poly |= ct.has_param_types_or_consts();
+            }
         }
 
         let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body };
@@ -408,7 +416,7 @@ fn check_unop(op: mir::UnOp) -> bool {
     }
 
     /// Builds the abstract const by walking the thir and bailing out when
-    /// encountering an unspported operation.
+    /// encountering an unsupported operation.
     fn build(mut self) -> Result<&'tcx [Node<'tcx>], ErrorGuaranteed> {
         debug!("Abstractconstbuilder::build: body={:?}", &*self.body);
         self.recurse_build(self.body_id)?;
@@ -637,6 +645,7 @@ pub(super) fn thir_abstract_const<'tcx>(
     }
 }
 
+#[instrument(skip(tcx), level = "debug")]
 pub(super) fn try_unify_abstract_consts<'tcx>(
     tcx: TyCtxt<'tcx>,
     (a, b): (ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()>),
@@ -701,7 +710,7 @@ struct ConstUnifyCtxt<'tcx> {
 
 impl<'tcx> ConstUnifyCtxt<'tcx> {
     // Substitutes generics repeatedly to allow AbstractConsts to unify where a
-    // ConstKind::Unevalated could be turned into an AbstractConst that would unify e.g.
+    // ConstKind::Unevaluated could be turned into an AbstractConst that would unify e.g.
     // Param(N) should unify with Param(T), substs: [Unevaluated("T2", [Unevaluated("T3", [Param(N)])])]
     #[inline]
     #[instrument(skip(self), level = "debug")]
@@ -806,3 +815,51 @@ fn try_unify(&self, a: AbstractConst<'tcx>, b: AbstractConst<'tcx>) -> bool {
         }
     }
 }
+
+/* Think I need these changes
+=======
+            match (a_ct, b_ct) {
+                (mir::ConstantKind::Ty(a_ct), mir::ConstantKind::Ty(b_ct)) => {
+                    match (a_ct.val(), b_ct.val()) {
+                        // We can just unify errors with everything to reduce the amount of
+                        // emitted errors here.
+                        (ty::ConstKind::Error(_), _) | (_, ty::ConstKind::Error(_)) => true,
+                        (ty::ConstKind::Param(a_param), ty::ConstKind::Param(b_param)) => {
+                            a_param == b_param
+                        }
+                        (ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => {
+                            a_val == b_val
+                        }
+
+                        // If we have `fn a<const N: usize>() -> [u8; N + 1]` and `fn b<const M: usize>() -> [u8; 1 + M]`
+                        // we do not want to use `assert_eq!(a(), b())` to infer that `N` and `M` have to be `1`. This
+                        // means that we only allow inference variables if they are equal.
+                        (ty::ConstKind::Infer(a_val), ty::ConstKind::Infer(b_val)) => {
+                            a_val == b_val
+                        }
+                        // We expand generic anonymous constants at the start of this function, so this
+                        // branch should only be taking when dealing with associated constants, at
+                        // which point directly comparing them seems like the desired behavior.
+                        //
+                        // FIXME(generic_const_exprs): This isn't actually the case.
+                        // We also take this branch for concrete anonymous constants and
+                        // expand generic anonymous constants with concrete substs.
+                        (ty::ConstKind::Unevaluated(a_uv), ty::ConstKind::Unevaluated(b_uv)) => {
+                            a_uv == b_uv
+                        }
+                        // FIXME(generic_const_exprs): We may want to either actually try
+                        // to evaluate `a_ct` and `b_ct` if they are are fully concrete or something like
+                        // this, for now we just return false here.
+                        _ => false,
+                    }
+                }
+                (mir::ConstantKind::Val(a_val, a_ty), mir::ConstantKind::Val(b_val, b_ty)) => {
+                    a_val == b_val && a_ty == b_ty
+                }
+                _ => {
+                    // FIXME Can it happen that we need to compare ConstantKind::Ty(ConstKind::Value)
+                    // with a ConstantKind::Val and vice versa?
+                    false
+>>>>>>> 6064f16d846 (change thir to use mir::ConstantKind instead of ty::Const)
+
+ */