From e1f408e6c8d440224dfa45f8b1a97ed84c790fcd Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Tue, 22 Sep 2020 09:42:29 +0200 Subject: [PATCH] const_evaluatable_checked: collect predicates from fn_sig --- compiler/rustc_typeck/src/collect.rs | 23 +++++++++++++++---- .../cross_crate_predicate.rs | 1 + .../cross_crate_predicate.stderr | 20 +++++++++++++++- .../from-sig-fail.rs | 11 +++++++++ .../from-sig-fail.stderr | 9 ++++++++ .../const_evaluatable_checked/from-sig.rs | 14 +++++++++++ 6 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.rs create mode 100644 src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.stderr create mode 100644 src/test/ui/const-generics/const_evaluatable_checked/from-sig.rs diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 458622dd65a39..d04b5cf588f72 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1678,8 +1678,10 @@ fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicate if tcx.features().const_evaluatable_checked { let const_evaluatable = const_evaluatable_predicates_of(tcx, def_id, &result); - result.predicates = - tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(const_evaluatable)); + if !const_evaluatable.is_empty() { + result.predicates = + tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(const_evaluatable)); + } } debug!("predicates_defined_on({:?}) = {:?}", def_id, result); @@ -1690,7 +1692,7 @@ pub fn const_evaluatable_predicates_of<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, predicates: &ty::GenericPredicates<'tcx>, -) -> impl Iterator, Span)> { +) -> Vec<(ty::Predicate<'tcx>, Span)> { #[derive(Default)] struct ConstCollector<'tcx> { ct: SmallVec<[(ty::WithOptConstParam, SubstsRef<'tcx>, Span); 4]>, @@ -1711,10 +1713,21 @@ pub fn const_evaluatable_predicates_of<'tcx>( collector.curr_span = span; 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)| { (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 diff --git a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs index 223699233298d..52b89cfa04588 100644 --- a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs +++ b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs @@ -8,6 +8,7 @@ fn user() { //~^ ERROR constant expression depends //~| ERROR constant expression depends //~| ERROR constant expression depends + //~| ERROR constant expression depends } fn main() {} diff --git a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr index 63abb782b93a3..e8afb495e602b 100644 --- a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr +++ b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr @@ -11,6 +11,19 @@ LL | [u8; std::mem::size_of::() - 1]: Sized, | = 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::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + ::: $DIR/auxiliary/const_evaluatable_lib.rs:6:41 + | +LL | [u8; std::mem::size_of::() - 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 --> $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::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + ::: $DIR/auxiliary/const_evaluatable_lib.rs:6:41 + | +LL | [u8; std::mem::size_of::() - 1]: Sized, + | ----- required by this bound in `test1::{{constant}}#1` | = 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 diff --git a/src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.rs b/src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.rs new file mode 100644 index 0000000000000..3da4688702c96 --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.rs @@ -0,0 +1,11 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +fn test() -> [u8; N - 1] { + //~^ ERROR evaluation of constant + todo!() +} + +fn main() { + test::<0>(); +} diff --git a/src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.stderr b/src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.stderr new file mode 100644 index 0000000000000..a5acfec34aa87 --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/from-sig-fail.rs:4:35 + | +LL | fn test() -> [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`. diff --git a/src/test/ui/const-generics/const_evaluatable_checked/from-sig.rs b/src/test/ui/const-generics/const_evaluatable_checked/from-sig.rs new file mode 100644 index 0000000000000..5c05a5acfe96d --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/from-sig.rs @@ -0,0 +1,14 @@ +// run-pass +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +struct Foo; + +fn test() -> Foo<{ N > 10 }> { + Foo +} + +fn main() { + let _: Foo = test::<12>(); + let _: Foo = test::<9>(); +}