}
}
+ query try_unify_abstract_consts(key: (
+ (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
+ (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>)
+ )) -> bool {
+ desc {
+ |tcx| "trying to unify the generic constants {} and {}",
+ tcx.def_path_str(key.0.0.did), tcx.def_path_str(key.1.0.did)
+ }
+ }
+
query mir_drops_elaborated_and_const_checked(
key: ty::WithOptConstParam<LocalDefId>
) -> &'tcx Steal<mir::Body<'tcx>> {
}
}
+impl<'tcx> Key
+ for (
+ (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
+ (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
+ )
+{
+ type CacheSelector = DefaultCacheSelector;
+
+ fn query_crate(&self) -> CrateNum {
+ (self.0).0.did.krate
+ }
+ fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
+ (self.0).0.did.default_span(tcx)
+ }
+}
+
impl<'tcx> Key for (LocalDefId, DefId, SubstsRef<'tcx>) {
type CacheSelector = DefaultCacheSelector;
new_val.map(ty::ConstKind::Value)
}
- // FIXME(const_generics): this is wrong, as it is a projection
+ (
+ ty::ConstKind::Unevaluated(a_def, a_substs, None),
+ ty::ConstKind::Unevaluated(b_def, b_substs, None),
+ ) if tcx.features().const_evaluatable_checked => {
+ if tcx.try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs))) {
+ Ok(a.val)
+ } else {
+ Err(TypeError::ConstMismatch(expected_found(relation, a, b)))
+ }
+ }
+
+ // While this is slightly incorrect, it shouldn't matter for `min_const_generics`
+ // and is the better alternative to waiting until `const_evaluatable_checked` can
+ // be stabilized.
(
ty::ConstKind::Unevaluated(a_def, a_substs, a_promoted),
ty::ConstKind::Unevaluated(b_def, b_substs, b_promoted),
}
}
-pub fn try_unify<'tcx>(tcx: TyCtxt<'tcx>, a: AbstractConst<'tcx>, b: AbstractConst<'tcx>) -> bool {
+pub(super) fn try_unify_abstract_consts<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ ((a, a_substs), (b, b_substs)): (
+ (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
+ (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
+ ),
+) -> bool {
+ if let Some(a) = AbstractConst::new(tcx, a, a_substs) {
+ if let Some(b) = AbstractConst::new(tcx, b, b_substs) {
+ return try_unify(tcx, a, b);
+ }
+ }
+
+ false
+}
+
+pub(super) fn try_unify<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ a: AbstractConst<'tcx>,
+ b: AbstractConst<'tcx>,
+) -> bool {
match (a.root(), b.root()) {
(Node::Leaf(a_ct), Node::Leaf(b_ct)) => {
let a_ct = a_ct.subst(tcx, a.substs);
ty::PredicateAtom::ConstEquate(c1, c2) => {
debug!("equating consts: c1={:?} c2={:?}", c1, c2);
+ if self.selcx.tcx().features().const_evaluatable_checked {
+ // 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:
+ if let (
+ ty::ConstKind::Unevaluated(a_def, a_substs, None),
+ ty::ConstKind::Unevaluated(b_def, b_substs, None),
+ ) = (c1.val, c2.val)
+ {
+ if self
+ .selcx
+ .tcx()
+ .try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs)))
+ {
+ return ProcessResult::Changed(vec![]);
+ }
+ }
+ }
let stalled_on = &mut pending_obligation.stalled_on;
ty::WithOptConstParam { did, const_param_did: Some(param_did) },
)
},
+ try_unify_abstract_consts: const_evaluatable::try_unify_abstract_consts,
..*providers
};
}
error: generic parameters must not be used inside of non trivial constant values
- --> $DIR/simple.rs:8:33
+ --> $DIR/simple.rs:8:53
|
-LL | type Arr<const N: usize> = [u8; N - 1];
- | ^ non-trivial anonymous constants must not depend on the parameter `N`
+LL | fn test<const N: usize>() -> [u8; N - 1] where [u8; N - 1]: Default {
+ | ^ non-trivial anonymous constants must not depend on the parameter `N`
|
= help: it is currently only allowed to use either `N` or `{ N }` as generic constants
-error: aborting due to previous error
+error: generic parameters must not be used inside of non trivial constant values
+ --> $DIR/simple.rs:8:35
+ |
+LL | fn test<const N: usize>() -> [u8; N - 1] where [u8; N - 1]: Default {
+ | ^ non-trivial anonymous constants must not depend on the parameter `N`
+ |
+ = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: aborting due to 2 previous errors
#![feature(const_evaluatable_checked)]
#![allow(incomplete_features)]
-type Arr<const N: usize> = [u8; N - 1];
-//[min]~^ ERROR generic parameters must not be used inside of non trivial constant values
-
-fn test<const N: usize>() -> Arr<N> where Arr<N>: Default {
+fn test<const N: usize>() -> [u8; N - 1] where [u8; N - 1]: Default {
+ //[min]~^ ERROR generic parameters
+ //[min]~| ERROR generic parameters
Default::default()
}