From f6725c0a9833b48d3d8bc463385872b3a5227dad Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 22 Dec 2022 07:19:15 +0000 Subject: [PATCH] fix fn_sig ice --- .../src/transform/check_consts/check.rs | 2 +- .../src/transform/check_consts/mod.rs | 13 ++++++++++++- .../non-const-op-const-closure-non-const-outer.rs | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const_closures/non-const-op-const-closure-non-const-outer.rs diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 38212496ec8..d4c75cd55ce 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -242,7 +242,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { // impl trait is gone in MIR, so check the return type of a const fn by its signature // instead of the type of the return place. self.span = body.local_decls[RETURN_PLACE].source_info.span; - let return_ty = tcx.fn_sig(def_id).output(); + let return_ty = self.ccx.fn_sig().output(); self.check_local_or_return_ty(return_ty.skip_binder(), RETURN_PLACE); } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index 0a90572d39e..b528bc92330 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -8,7 +8,7 @@ use rustc_attr as attr; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::mir; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt, PolyFnSig}; use rustc_span::Symbol; pub use self::qualifs::Qualif; @@ -64,6 +64,17 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> { fn is_async(&self) -> bool { self.tcx.asyncness(self.def_id()).is_async() } + + pub fn fn_sig(&self) -> PolyFnSig<'tcx> { + let did = self.def_id().to_def_id(); + if self.tcx.is_closure(did) { + let ty = self.tcx.type_of(did); + let ty::Closure(_, substs) = ty.kind() else { bug!("type_of closure not ty::Closure") }; + substs.as_closure().sig() + } else { + self.tcx.fn_sig(did) + } + } } pub fn rustc_allow_const_fn_unstable( diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_closures/non-const-op-const-closure-non-const-outer.rs b/src/test/ui/rfc-2632-const-trait-impl/const_closures/non-const-op-const-closure-non-const-outer.rs new file mode 100644 index 00000000000..cd8bb5963ad --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const_closures/non-const-op-const-closure-non-const-outer.rs @@ -0,0 +1,15 @@ +#![feature(const_closures, const_trait_impl)] +#![allow(incomplete_features)] + +trait Foo { + fn foo(&self); +} + +impl Foo for () { + fn foo(&self) {} +} + +fn main() { + (const || { (()).foo() })(); + //~^ ERROR: cannot call non-const fn +}