Skip to content

Commit e1f408e

Browse files
committed
const_evaluatable_checked: collect predicates from fn_sig
1 parent 78a0894 commit e1f408e

File tree

6 files changed

+72
-6
lines changed

6 files changed

+72
-6
lines changed

compiler/rustc_typeck/src/collect.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,8 +1678,10 @@ fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicate
16781678

16791679
if tcx.features().const_evaluatable_checked {
16801680
let const_evaluatable = const_evaluatable_predicates_of(tcx, def_id, &result);
1681-
result.predicates =
1682-
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(const_evaluatable));
1681+
if !const_evaluatable.is_empty() {
1682+
result.predicates =
1683+
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(const_evaluatable));
1684+
}
16831685
}
16841686

16851687
debug!("predicates_defined_on({:?}) = {:?}", def_id, result);
@@ -1690,7 +1692,7 @@ pub fn const_evaluatable_predicates_of<'tcx>(
16901692
tcx: TyCtxt<'tcx>,
16911693
def_id: DefId,
16921694
predicates: &ty::GenericPredicates<'tcx>,
1693-
) -> impl Iterator<Item = (ty::Predicate<'tcx>, Span)> {
1695+
) -> Vec<(ty::Predicate<'tcx>, Span)> {
16941696
#[derive(Default)]
16951697
struct ConstCollector<'tcx> {
16961698
ct: SmallVec<[(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>, Span); 4]>,
@@ -1711,10 +1713,21 @@ pub fn const_evaluatable_predicates_of<'tcx>(
17111713
collector.curr_span = span;
17121714
pred.visit_with(&mut collector);
17131715
}
1714-
warn!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.ct);
1716+
1717+
match tcx.def_kind(def_id) {
1718+
DefKind::Fn | DefKind::AssocFn => {
1719+
tcx.fn_sig(def_id).visit_with(&mut collector);
1720+
}
1721+
_ => (),
1722+
}
1723+
debug!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.ct);
1724+
1725+
// We only want unique const evaluatable predicates.
1726+
collector.ct.sort();
1727+
collector.ct.dedup();
17151728
collector.ct.into_iter().map(move |(def_id, subst, span)| {
17161729
(ty::PredicateAtom::ConstEvaluatable(def_id, subst).to_predicate(tcx), span)
1717-
})
1730+
}).collect()
17181731
}
17191732

17201733
/// Returns a list of all type predicates (explicit and implicit) for the definition with

src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ fn user<T>() {
88
//~^ ERROR constant expression depends
99
//~| ERROR constant expression depends
1010
//~| ERROR constant expression depends
11+
//~| ERROR constant expression depends
1112
}
1213

1314
fn main() {}

src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
1111
|
1212
= note: this may fail depending on what value the parameter takes
1313

14+
error: constant expression depends on a generic parameter
15+
--> $DIR/cross_crate_predicate.rs:7:13
16+
|
17+
LL | let _ = const_evaluatable_lib::test1::<T>();
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
19+
|
20+
::: $DIR/auxiliary/const_evaluatable_lib.rs:6:41
21+
|
22+
LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
23+
| ----- required by this bound in `test1`
24+
|
25+
= note: this may fail depending on what value the parameter takes
26+
1427
error: constant expression depends on a generic parameter
1528
--> $DIR/cross_crate_predicate.rs:7:13
1629
|
@@ -29,8 +42,13 @@ error: constant expression depends on a generic parameter
2942
|
3043
LL | let _ = const_evaluatable_lib::test1::<T>();
3144
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
45+
|
46+
::: $DIR/auxiliary/const_evaluatable_lib.rs:6:41
47+
|
48+
LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
49+
| ----- required by this bound in `test1::{{constant}}#1`
3250
|
3351
= note: this may fail depending on what value the parameter takes
3452

35-
error: aborting due to 3 previous errors
53+
error: aborting due to 4 previous errors
3654

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(const_generics, const_evaluatable_checked)]
2+
#![allow(incomplete_features)]
3+
4+
fn test<const N: usize>() -> [u8; N - 1] {
5+
//~^ ERROR evaluation of constant
6+
todo!()
7+
}
8+
9+
fn main() {
10+
test::<0>();
11+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0080]: evaluation of constant value failed
2+
--> $DIR/from-sig-fail.rs:4:35
3+
|
4+
LL | fn test<const N: usize>() -> [u8; N - 1] {
5+
| ^^^^^ attempt to compute `0_usize - 1_usize` which would overflow
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0080`.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// run-pass
2+
#![feature(const_generics, const_evaluatable_checked)]
3+
#![allow(incomplete_features)]
4+
5+
struct Foo<const B: bool>;
6+
7+
fn test<const N: usize>() -> Foo<{ N > 10 }> {
8+
Foo
9+
}
10+
11+
fn main() {
12+
let _: Foo<true> = test::<12>();
13+
let _: Foo<false> = test::<9>();
14+
}

0 commit comments

Comments
 (0)