const_evaluatable_checked: collect predicates from fn_sig
This commit is contained in:
parent
78a089487b
commit
e1f408e6c8
|
@ -1678,8 +1678,10 @@ fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicate
|
||||||
|
|
||||||
if tcx.features().const_evaluatable_checked {
|
if tcx.features().const_evaluatable_checked {
|
||||||
let const_evaluatable = const_evaluatable_predicates_of(tcx, def_id, &result);
|
let const_evaluatable = const_evaluatable_predicates_of(tcx, def_id, &result);
|
||||||
result.predicates =
|
if !const_evaluatable.is_empty() {
|
||||||
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(const_evaluatable));
|
result.predicates =
|
||||||
|
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(const_evaluatable));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("predicates_defined_on({:?}) = {:?}", def_id, result);
|
debug!("predicates_defined_on({:?}) = {:?}", def_id, result);
|
||||||
|
@ -1690,7 +1692,7 @@ pub fn const_evaluatable_predicates_of<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
predicates: &ty::GenericPredicates<'tcx>,
|
predicates: &ty::GenericPredicates<'tcx>,
|
||||||
) -> impl Iterator<Item = (ty::Predicate<'tcx>, Span)> {
|
) -> Vec<(ty::Predicate<'tcx>, Span)> {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct ConstCollector<'tcx> {
|
struct ConstCollector<'tcx> {
|
||||||
ct: SmallVec<[(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>, Span); 4]>,
|
ct: SmallVec<[(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>, Span); 4]>,
|
||||||
|
@ -1711,10 +1713,21 @@ pub fn const_evaluatable_predicates_of<'tcx>(
|
||||||
collector.curr_span = span;
|
collector.curr_span = span;
|
||||||
pred.visit_with(&mut collector);
|
pred.visit_with(&mut collector);
|
||||||
}
|
}
|
||||||
warn!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.ct);
|
|
||||||
|
match tcx.def_kind(def_id) {
|
||||||
|
DefKind::Fn | DefKind::AssocFn => {
|
||||||
|
tcx.fn_sig(def_id).visit_with(&mut collector);
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
debug!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.ct);
|
||||||
|
|
||||||
|
// We only want unique const evaluatable predicates.
|
||||||
|
collector.ct.sort();
|
||||||
|
collector.ct.dedup();
|
||||||
collector.ct.into_iter().map(move |(def_id, subst, span)| {
|
collector.ct.into_iter().map(move |(def_id, subst, span)| {
|
||||||
(ty::PredicateAtom::ConstEvaluatable(def_id, subst).to_predicate(tcx), span)
|
(ty::PredicateAtom::ConstEvaluatable(def_id, subst).to_predicate(tcx), span)
|
||||||
})
|
}).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of all type predicates (explicit and implicit) for the definition with
|
/// Returns a list of all type predicates (explicit and implicit) for the definition with
|
||||||
|
|
|
@ -8,6 +8,7 @@ fn user<T>() {
|
||||||
//~^ ERROR constant expression depends
|
//~^ ERROR constant expression depends
|
||||||
//~| ERROR constant expression depends
|
//~| ERROR constant expression depends
|
||||||
//~| ERROR constant expression depends
|
//~| ERROR constant expression depends
|
||||||
|
//~| ERROR constant expression depends
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -11,6 +11,19 @@ LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
|
||||||
|
|
|
|
||||||
= note: this may fail depending on what value the parameter takes
|
= note: this may fail depending on what value the parameter takes
|
||||||
|
|
||||||
|
error: constant expression depends on a generic parameter
|
||||||
|
--> $DIR/cross_crate_predicate.rs:7:13
|
||||||
|
|
|
||||||
|
LL | let _ = const_evaluatable_lib::test1::<T>();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
::: $DIR/auxiliary/const_evaluatable_lib.rs:6:41
|
||||||
|
|
|
||||||
|
LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
|
||||||
|
| ----- required by this bound in `test1`
|
||||||
|
|
|
||||||
|
= note: this may fail depending on what value the parameter takes
|
||||||
|
|
||||||
error: constant expression depends on a generic parameter
|
error: constant expression depends on a generic parameter
|
||||||
--> $DIR/cross_crate_predicate.rs:7:13
|
--> $DIR/cross_crate_predicate.rs:7:13
|
||||||
|
|
|
|
||||||
|
@ -29,8 +42,13 @@ error: constant expression depends on a generic parameter
|
||||||
|
|
|
|
||||||
LL | let _ = const_evaluatable_lib::test1::<T>();
|
LL | let _ = const_evaluatable_lib::test1::<T>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
::: $DIR/auxiliary/const_evaluatable_lib.rs:6:41
|
||||||
|
|
|
||||||
|
LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
|
||||||
|
| ----- required by this bound in `test1::{{constant}}#1`
|
||||||
|
|
|
|
||||||
= note: this may fail depending on what value the parameter takes
|
= note: this may fail depending on what value the parameter takes
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#![feature(const_generics, const_evaluatable_checked)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
fn test<const N: usize>() -> [u8; N - 1] {
|
||||||
|
//~^ ERROR evaluation of constant
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test::<0>();
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $DIR/from-sig-fail.rs:4:35
|
||||||
|
|
|
||||||
|
LL | fn test<const N: usize>() -> [u8; N - 1] {
|
||||||
|
| ^^^^^ attempt to compute `0_usize - 1_usize` which would overflow
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
|
@ -0,0 +1,14 @@
|
||||||
|
// run-pass
|
||||||
|
#![feature(const_generics, const_evaluatable_checked)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
struct Foo<const B: bool>;
|
||||||
|
|
||||||
|
fn test<const N: usize>() -> Foo<{ N > 10 }> {
|
||||||
|
Foo
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _: Foo<true> = test::<12>();
|
||||||
|
let _: Foo<false> = test::<9>();
|
||||||
|
}
|
Loading…
Reference in New Issue