X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_trait_selection%2Fsrc%2Ftraits%2Fconst_evaluatable.rs;h=709dd346efcc5203ce4f68996a29af983e3f3ecf;hb=ac60db231c96738b874fb31a755ef49a0d71926c;hp=959b644becd9b4012c8036619f75498ec49043f0;hpb=a8be562bdfeb775768ec5ca7a6c4e07809a1f829;p=rust.git diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 959b644becd..709dd346efc 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -168,8 +168,7 @@ enum FailureKind { "#![feature(generic_const_exprs)]\n".to_string(), rustc_errors::Applicability::MaybeIncorrect, ) - .emit(); - rustc_errors::FatalError.raise(); + .emit() } debug!(?concrete, "is_const_evaluatable"); @@ -377,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 }; @@ -409,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)?; @@ -638,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, ()>), @@ -702,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")] @@ -807,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() -> [u8; N + 1]` and `fn b() -> [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) + + */