diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index ffddf6f73aaf0..e58cb2ff59209 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2154,11 +2154,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported") } // FIXME(const_generics): create real const to allow fn items as const paths - Res::Def(DefKind::Fn | DefKind::AssocFn, _) => ty::Const::new_error_with_message( - tcx, - span, - "fn items cannot be used as const args", - ), + Res::Def(DefKind::Fn | DefKind::AssocFn, did) => { + self.dcx().span_delayed_bug(span, "function items cannot be used as const args"); + let args = self.lower_generic_args_of_path_segment( + span, + did, + path.segments.last().unwrap(), + ); + ty::Const::new_value(tcx, ty::ValTree::zst(), Ty::new_fn_def(tcx, did, args)) + } // Exhaustive match to be clear about what exactly we're considering to be // an invalid Res for a const path. diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index feae8ea312eaa..5a88e315b399f 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1800,7 +1800,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } let u8_type = self.tcx().types.u8; - match (cv.valtree, cv.ty.kind()) { + match (cv.valtree, *cv.ty.kind()) { (ty::ValTree::Branch(_), ty::Ref(_, inner_ty, _)) => match inner_ty.kind() { ty::Slice(t) if *t == u8_type => { let bytes = cv.try_to_raw_bytes(self.tcx()).unwrap_or_else(|| { @@ -1820,13 +1820,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { return Ok(()); } _ => { - let cv = ty::Value { valtree: cv.valtree, ty: *inner_ty }; + let cv = ty::Value { valtree: cv.valtree, ty: inner_ty }; p!("&"); p!(pretty_print_const_valtree(cv, print_ty)); return Ok(()); } }, - (ty::ValTree::Branch(_), ty::Array(t, _)) if *t == u8_type => { + (ty::ValTree::Branch(_), ty::Array(t, _)) if t == u8_type => { let bytes = cv.try_to_raw_bytes(self.tcx()).unwrap_or_else(|| { bug!("expected to convert valtree to raw bytes for type {:?}", t) }); @@ -1893,11 +1893,16 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } (ty::ValTree::Leaf(leaf), ty::Ref(_, inner_ty, _)) => { p!(write("&")); - return self.pretty_print_const_scalar_int(leaf, *inner_ty, print_ty); + return self.pretty_print_const_scalar_int(leaf, inner_ty, print_ty); } (ty::ValTree::Leaf(leaf), _) => { return self.pretty_print_const_scalar_int(leaf, cv.ty, print_ty); } + (_, ty::FnDef(def_id, args)) => { + // Never allowed today, but we still encounter them in invalid const args. + p!(print_value_path(def_id, args)); + return Ok(()); + } // FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading // their fields instead of just dumping the memory. _ => {} diff --git a/tests/ui/const-generics/mgca/unexpected-fn-item-in-array.rs b/tests/ui/const-generics/mgca/unexpected-fn-item-in-array.rs new file mode 100644 index 0000000000000..1c3274f6a3764 --- /dev/null +++ b/tests/ui/const-generics/mgca/unexpected-fn-item-in-array.rs @@ -0,0 +1,13 @@ +// Make sure we don't ICE when encountering an fn item during lowering in mGCA. + +#![feature(min_generic_const_args)] +//~^ WARN the feature `min_generic_const_args` is incomplete + +trait A {} + +impl A<[usize; fn_item]> for () {} +//~^ ERROR the constant `fn_item` is not of type `usize` + +fn fn_item() {} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/unexpected-fn-item-in-array.stderr b/tests/ui/const-generics/mgca/unexpected-fn-item-in-array.stderr new file mode 100644 index 0000000000000..89fc8270e3e74 --- /dev/null +++ b/tests/ui/const-generics/mgca/unexpected-fn-item-in-array.stderr @@ -0,0 +1,19 @@ +warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/unexpected-fn-item-in-array.rs:3:12 + | +LL | #![feature(min_generic_const_args)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: the constant `fn_item` is not of type `usize` + --> $DIR/unexpected-fn-item-in-array.rs:8:6 + | +LL | impl A<[usize; fn_item]> for () {} + | ^^^^^^^^^^^^^^^^^^^ expected `usize`, found fn item + | + = note: the length of array `[usize; fn_item]` must be type `usize` + +error: aborting due to 1 previous error; 1 warning emitted +