From fc06a57a786de3efc723c9c00085f481157b72df Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Wed, 7 Jan 2026 19:47:02 +0900 Subject: [PATCH 1/4] Introduce hir::ConstArgKind::Array --- compiler/rustc_ast_lowering/src/lib.rs | 19 +++++++++++++++++++ compiler/rustc_hir/src/hir.rs | 8 ++++++++ compiler/rustc_hir/src/intravisit.rs | 6 ++++++ .../src/hir_ty_lowering/mod.rs | 3 +++ compiler/rustc_hir_pretty/src/lib.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 1 + compiler/rustc_resolve/src/def_collector.rs | 2 +- src/librustdoc/clean/mod.rs | 3 +++ 8 files changed, 42 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 42eb8673f30c0..de403a2628795 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2517,6 +2517,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span, } } + ExprKind::Array(elements) => { + let lowered_elems = self.arena.alloc_from_iter(elements.iter().map(|element| { + let const_arg = if let ExprKind::ConstBlock(anon_const) = &element.kind { + let def_id = self.local_def_id(anon_const.id); + assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id)); + self.lower_anon_const_to_const_arg(anon_const) + } else { + self.lower_expr_to_const_arg_direct(element) + }; + &*self.arena.alloc(const_arg) + })); + let array_expr = self.arena.alloc(hir::ConstArgArrayExpr { + span: self.lower_span(expr.span), + elems: lowered_elems, + }); + + ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Array(array_expr) } + } ExprKind::Underscore => ConstArg { hir_id: self.lower_node_id(expr.id), kind: hir::ConstArgKind::Infer(()), @@ -2532,6 +2550,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | ExprKind::Struct(..) | ExprKind::Call(..) | ExprKind::Tup(..) + | ExprKind::Array(..) ) { return self.lower_expr_to_const_arg_direct(expr); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 2fb6daf6469b7..055df9c2a0852 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -513,6 +513,8 @@ pub enum ConstArgKind<'hir, Unambig = ()> { Struct(QPath<'hir>, &'hir [&'hir ConstArgExprField<'hir>]), /// Tuple constructor variant TupleCall(QPath<'hir>, &'hir [&'hir ConstArg<'hir>]), + /// Array literal argument + Array(&'hir ConstArgArrayExpr<'hir>), /// Error const Error(ErrorGuaranteed), /// This variant is not always used to represent inference consts, sometimes @@ -529,6 +531,12 @@ pub struct ConstArgExprField<'hir> { pub expr: &'hir ConstArg<'hir>, } +#[derive(Clone, Copy, Debug, HashStable_Generic)] +pub struct ConstArgArrayExpr<'hir> { + pub span: Span, + pub elems: &'hir [&'hir ConstArg<'hir>], +} + #[derive(Clone, Copy, Debug, HashStable_Generic)] pub struct InferArg { #[stable_hasher(ignore)] diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index e5e6fc7b1d8de..d1b75325af268 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1101,6 +1101,12 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>( } V::Result::output() } + ConstArgKind::Array(array_expr) => { + for arg in array_expr.elems { + try_visit!(visitor.visit_const_arg_unambig(*arg)); + } + V::Result::output() + } ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, qpath.span()), ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon), ConstArgKind::Error(_) => V::Result::output(), // errors and spans are not important 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 1dd9bff425759..42893906a3861 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2389,6 +2389,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::ConstArgKind::TupleCall(qpath, args) => { self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span) } + hir::ConstArgKind::Array(_array_expr) => { + span_bug!(const_arg.span(), "lowering `{:?}` is not yet implemented", const_arg) + } hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon), hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span), hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e), diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 37fa18c00887e..e0e9fe7758535 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1153,6 +1153,7 @@ impl<'a> State<'a> { } ConstArgKind::Struct(qpath, fields) => self.print_const_struct(qpath, fields), ConstArgKind::TupleCall(qpath, args) => self.print_const_ctor(qpath, args), + ConstArgKind::Array(..) => self.word("/* ARRAY EXPR */"), ConstArgKind::Path(qpath) => self.print_qpath(qpath, true), ConstArgKind::Anon(anon) => self.print_anon_const(anon), ConstArgKind::Error(_) => self.word("/*ERROR*/"), diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index c85327dc3db19..fd0fcb18bfe16 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1441,6 +1441,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // Skip encoding defs for these as they should not have had a `DefId` created hir::ConstArgKind::Error(..) | hir::ConstArgKind::Struct(..) + | hir::ConstArgKind::Array(..) | hir::ConstArgKind::TupleCall(..) | hir::ConstArgKind::Tup(..) | hir::ConstArgKind::Path(..) diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index b392b7747b554..ea5640ecc1fa9 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -419,7 +419,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { // Avoid overwriting `const_arg_context` as we may want to treat const blocks // as being anon consts if we are inside a const argument. - ExprKind::Struct(_) | ExprKind::Call(..) | ExprKind::Tup(..) => { + ExprKind::Struct(_) | ExprKind::Call(..) | ExprKind::Tup(..) | ExprKind::Array(..) => { return visit::walk_expr(self, expr); } // FIXME(mgca): we may want to handle block labels in some manner diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 817eda4c52ecc..c8e38330b82cf 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -329,6 +329,8 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind hir::ConstArgKind::Tup(..) => { // FIXME(mgca): proper printing :3 ConstantKind::Path { path: "/* TUPLE EXPR */".to_string().into() } + hir::ConstArgKind::Array(..) => { + ConstantKind::Path { path: "/* ARRAY EXPR */".to_string().into() } } hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body }, hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => ConstantKind::Infer, @@ -1818,6 +1820,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T | hir::ConstArgKind::Path(..) | hir::ConstArgKind::TupleCall(..) | hir::ConstArgKind::Tup(..) + | hir::ConstArgKind::Array(..) | hir::ConstArgKind::Literal(..) => { let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No); print_const(cx, ct) From 618b0b5464b8c078fbfaea3f3181d7248072a183 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Thu, 8 Jan 2026 10:35:52 +0900 Subject: [PATCH 2/4] Lower hir::ConstArgKind::Array to a ValTree --- compiler/rustc_ast_lowering/src/lib.rs | 6 +++- .../src/hir_ty_lowering/mod.rs | 34 +++++++++++++++++-- src/librustdoc/clean/mod.rs | 1 + tests/ui/const-generics/mgca/array-expr.rs | 24 +++++++++++++ .../ui/const-generics/mgca/array-expr.stderr | 14 ++++++++ 5 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 tests/ui/const-generics/mgca/array-expr.rs create mode 100644 tests/ui/const-generics/mgca/array-expr.stderr diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index de403a2628795..350fa04ab3bdc 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2533,7 +2533,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { elems: lowered_elems, }); - ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Array(array_expr) } + ConstArg { + hir_id: self.next_id(), + kind: hir::ConstArgKind::Array(array_expr), + span, + } } ExprKind::Underscore => ConstArg { hir_id: self.lower_node_id(expr.id), 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 42893906a3861..6f44a728242d7 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2389,9 +2389,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::ConstArgKind::TupleCall(qpath, args) => { self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span) } - hir::ConstArgKind::Array(_array_expr) => { - span_bug!(const_arg.span(), "lowering `{:?}` is not yet implemented", const_arg) - } + hir::ConstArgKind::Array(array_expr) => self.lower_const_arg_array(array_expr, feed), hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon), hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span), hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e), @@ -2405,6 +2403,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + fn lower_const_arg_array( + &self, + array_expr: &'tcx hir::ConstArgArrayExpr<'tcx>, + feed: FeedConstTy<'tcx>, + ) -> Const<'tcx> { + let tcx = self.tcx(); + + let FeedConstTy::WithTy(ty) = feed else { + return Const::new_error_with_message(tcx, array_expr.span, "unsupported const array"); + }; + + let ty::Array(elem_ty, _) = ty.kind() else { + return Const::new_error_with_message( + tcx, + array_expr.span, + "const array must have an array type", + ); + }; + + let elems = array_expr + .elems + .iter() + .map(|elem| self.lower_const_arg(elem, FeedConstTy::WithTy(*elem_ty))) + .collect::>(); + + let valtree = ty::ValTree::from_branches(tcx, elems); + + ty::Const::new_value(tcx, valtree, ty) + } + fn lower_const_arg_tuple_call( &self, hir_id: HirId, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c8e38330b82cf..597a85f397695 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -329,6 +329,7 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind hir::ConstArgKind::Tup(..) => { // FIXME(mgca): proper printing :3 ConstantKind::Path { path: "/* TUPLE EXPR */".to_string().into() } + } hir::ConstArgKind::Array(..) => { ConstantKind::Path { path: "/* ARRAY EXPR */".to_string().into() } } diff --git a/tests/ui/const-generics/mgca/array-expr.rs b/tests/ui/const-generics/mgca/array-expr.rs new file mode 100644 index 0000000000000..099fee7ecd031 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr.rs @@ -0,0 +1,24 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] + +fn takes_array() {} + +fn generic_caller() { + takes_array::<{ [N, N2, N] }>(); // ok + + takes_array::<{ [N, N2, const { 1 }] }>(); // ok + + takes_array::<{ [N, N2, const { 1 + 1 }] }>(); // ok + + takes_array::<{ [N, N2, 1] }>(); // ok + + takes_array::<{ [1, 1u32, 1_u32] }>(); // ok + + takes_array::<{ [N, N2, 1 + 1] }>(); // not implemented + //~^ ERROR complex const arguments must be placed inside of a `const` block + + takes_array::<{ [N; 3] }>(); // not implemented + //~^ ERROR complex const arguments must be placed inside of a `const` block +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr.stderr b/tests/ui/const-generics/mgca/array-expr.stderr new file mode 100644 index 0000000000000..0dda791c2e106 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr.stderr @@ -0,0 +1,14 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array-expr.rs:17:29 + | +LL | takes_array::<{ [N, N2, 1 + 1] }>(); // not implemented + | ^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array-expr.rs:20:19 + | +LL | takes_array::<{ [N; 3] }>(); // not implemented + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors + From 522be7f1c0430cd7201b1f75ec72cb473099835c Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Thu, 8 Jan 2026 12:19:43 +0900 Subject: [PATCH 3/4] Fix clippy --- src/tools/clippy/clippy_lints/src/utils/author.rs | 1 + src/tools/clippy/clippy_utils/src/consts.rs | 1 + src/tools/clippy/clippy_utils/src/hir_utils.rs | 11 +++++++++++ 3 files changed, 13 insertions(+) diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index acea701b2e830..8243077cab897 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -321,6 +321,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { }, ConstArgKind::Struct(..) => chain!(self, "let ConstArgKind::Struct(..) = {const_arg}.kind"), ConstArgKind::TupleCall(..) => chain!(self, "let ConstArgKind::TupleCall(..) = {const_arg}.kind"), + ConstArgKind::Array(..) => chain!(self, "let ConstArgKind::Array(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"), diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 538f1fd2628c9..e2ada37d53b39 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -1144,6 +1144,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx | ConstArgKind::Tup(..) | ConstArgKind::Literal(..) | ConstArgKind::TupleCall(..) + | ConstArgKind::Array(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => None, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 0bb641568879c..c7bb3a064a093 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -687,6 +687,11 @@ impl HirEqInterExpr<'_, '_, '_> { .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) }, (ConstArgKind::Literal(kind_l), ConstArgKind::Literal(kind_r)) => kind_l == kind_r, + (ConstArgKind::Array(l_arr), ConstArgKind::Array(r_arr)) => { + l_arr.elems.len() == r_arr.elems.len() + && l_arr.elems.iter().zip(r_arr.elems.iter()) + .all(|(l_elem, r_elem)| self.eq_const_arg(l_elem, r_elem)) + } // Use explicit match for now since ConstArg is undergoing flux. ( ConstArgKind::Path(..) @@ -696,6 +701,7 @@ impl HirEqInterExpr<'_, '_, '_> { | ConstArgKind::Infer(..) | ConstArgKind::Struct(..) | ConstArgKind::Literal(..) + | ConstArgKind::Array(..) | ConstArgKind::Error(..), _, ) => false, @@ -1575,6 +1581,11 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_const_arg(arg); } }, + ConstArgKind::Array(array_expr) => { + for elem in array_expr.elems { + self.hash_const_arg(elem); + } + }, ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, ConstArgKind::Literal(lit) => lit.hash(&mut self.s), } From f2f45ffddd584377b36e1da628b79d05d538a2a4 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Fri, 9 Jan 2026 14:13:41 +0900 Subject: [PATCH 4/4] Add mGCA array expression tests --- .../const-generics/mgca/array-expr-complex.rs | 16 ++++++++++++ .../mgca/array-expr-complex.stderr | 20 +++++++++++++++ .../const-generics/mgca/array-expr-empty.rs | 9 +++++++ .../mgca/array-expr-empty.stderr | 8 ++++++ .../const-generics/mgca/array-expr-simple.rs | 25 +++++++++++++++++++ .../mgca/array-expr-with-assoc-const.rs | 18 +++++++++++++ .../mgca/array-expr-with-macro.rs | 18 +++++++++++++ .../mgca/array-expr-with-struct.rs | 20 +++++++++++++++ .../mgca/array-expr-with-tuple.rs | 13 ++++++++++ tests/ui/const-generics/mgca/array-expr.rs | 24 ------------------ .../ui/const-generics/mgca/array-expr.stderr | 14 ----------- 11 files changed, 147 insertions(+), 38 deletions(-) create mode 100644 tests/ui/const-generics/mgca/array-expr-complex.rs create mode 100644 tests/ui/const-generics/mgca/array-expr-complex.stderr create mode 100644 tests/ui/const-generics/mgca/array-expr-empty.rs create mode 100644 tests/ui/const-generics/mgca/array-expr-empty.stderr create mode 100644 tests/ui/const-generics/mgca/array-expr-simple.rs create mode 100644 tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs create mode 100644 tests/ui/const-generics/mgca/array-expr-with-macro.rs create mode 100644 tests/ui/const-generics/mgca/array-expr-with-struct.rs create mode 100644 tests/ui/const-generics/mgca/array-expr-with-tuple.rs delete mode 100644 tests/ui/const-generics/mgca/array-expr.rs delete mode 100644 tests/ui/const-generics/mgca/array-expr.stderr diff --git a/tests/ui/const-generics/mgca/array-expr-complex.rs b/tests/ui/const-generics/mgca/array-expr-complex.rs new file mode 100644 index 0000000000000..3e8320bc94de2 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-complex.rs @@ -0,0 +1,16 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] + +fn takes_array() {} + +fn generic_caller() { + // not supported yet + takes_array::<{ [1, 2, 1 + 2] }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block + takes_array::<{ [X; 3] }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block + takes_array::<{ [0; Y] }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-complex.stderr b/tests/ui/const-generics/mgca/array-expr-complex.stderr new file mode 100644 index 0000000000000..beac1aa232f2f --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-complex.stderr @@ -0,0 +1,20 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array-expr-complex.rs:8:28 + | +LL | takes_array::<{ [1, 2, 1 + 2] }>(); + | ^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array-expr-complex.rs:10:19 + | +LL | takes_array::<{ [X; 3] }>(); + | ^^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array-expr-complex.rs:12:19 + | +LL | takes_array::<{ [0; Y] }>(); + | ^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/const-generics/mgca/array-expr-empty.rs b/tests/ui/const-generics/mgca/array-expr-empty.rs new file mode 100644 index 0000000000000..d37c6f2fcfe35 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-empty.rs @@ -0,0 +1,9 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +fn takes_empty_array() {} +//~^ ERROR: expected type, found `]` + +fn main() { + takes_empty_array::<{ [] }>(); +} diff --git a/tests/ui/const-generics/mgca/array-expr-empty.stderr b/tests/ui/const-generics/mgca/array-expr-empty.stderr new file mode 100644 index 0000000000000..91340e621acbb --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-empty.stderr @@ -0,0 +1,8 @@ +error: expected type, found `]` + --> $DIR/array-expr-empty.rs:4:32 + | +LL | fn takes_empty_array() {} + | ^ expected type + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/array-expr-simple.rs b/tests/ui/const-generics/mgca/array-expr-simple.rs new file mode 100644 index 0000000000000..44feeccb4f9f2 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-simple.rs @@ -0,0 +1,25 @@ +//@ run-pass +#![expect(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] +#![allow(dead_code)] + +fn takes_array_u32() {} +fn takes_array_bool() {} +fn takes_nested_array() {} +fn takes_empty_array() {} + +fn generic_caller() { + takes_array_u32::<{ [X, Y, X] }>(); + takes_array_u32::<{ [X, Y, const { 1 }] }>(); + takes_array_u32::<{ [X, Y, const { 1 + 1 }] }>(); + takes_array_u32::<{ [2_002, 2u32, 1_u32] }>(); + + takes_array_bool::<{ [true, false] }>(); + + takes_nested_array::<{ [[X, Y], [3, 4]] }>(); + takes_nested_array::<{ [[1u32, 2_u32], [const { 3 }, 4]] }>(); + + takes_empty_array::<{ [] }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs b/tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs new file mode 100644 index 0000000000000..47ecbfa6b7e15 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs @@ -0,0 +1,18 @@ +//@ run-pass +#![expect(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] +#![allow(dead_code)] + +fn takes_array() {} + +trait Trait { + #[type_const] + const ASSOC: u32; +} + +fn generic_caller() { + takes_array::<{ [T::ASSOC, N, T::ASSOC] }>(); + takes_array::<{ [1_u32, T::ASSOC, 2] }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-with-macro.rs b/tests/ui/const-generics/mgca/array-expr-with-macro.rs new file mode 100644 index 0000000000000..aef5acc1c8030 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-with-macro.rs @@ -0,0 +1,18 @@ +//@ run-pass +#![expect(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] +#![allow(dead_code)] + +macro_rules! make_array { + ($n:expr, $m:expr, $p:expr) => { + [N, $m, $p] + }; +} + +fn takes_array() {} + +fn generic_caller() { + takes_array::<{ make_array!(N, 2, 3) }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-with-struct.rs b/tests/ui/const-generics/mgca/array-expr-with-struct.rs new file mode 100644 index 0000000000000..883af57e918e3 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-with-struct.rs @@ -0,0 +1,20 @@ +//@ run-pass +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +#![allow(dead_code)] + +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] +struct Container { + values: [u32; 3], +} + +fn takes_container() {} + +fn generic_caller() { + takes_container::<{ Container { values: [N, M, 1] } }>(); + takes_container::<{ Container { values: [1, 2, 3] } }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-with-tuple.rs b/tests/ui/const-generics/mgca/array-expr-with-tuple.rs new file mode 100644 index 0000000000000..004663dcefaba --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-with-tuple.rs @@ -0,0 +1,13 @@ +//@ run-pass +#![feature(min_generic_const_args, adt_const_params, unsized_const_params)] +#![expect(incomplete_features)] +#![allow(dead_code)] + +fn takes_tuple() {} + +fn generic_caller() { + takes_tuple::<{ ([N, M], 5, [M, N]) }>(); + takes_tuple::<{ ([1, 2], 3, [4, 5]) }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr.rs b/tests/ui/const-generics/mgca/array-expr.rs deleted file mode 100644 index 099fee7ecd031..0000000000000 --- a/tests/ui/const-generics/mgca/array-expr.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![expect(incomplete_features)] -#![feature(min_generic_const_args, adt_const_params)] - -fn takes_array() {} - -fn generic_caller() { - takes_array::<{ [N, N2, N] }>(); // ok - - takes_array::<{ [N, N2, const { 1 }] }>(); // ok - - takes_array::<{ [N, N2, const { 1 + 1 }] }>(); // ok - - takes_array::<{ [N, N2, 1] }>(); // ok - - takes_array::<{ [1, 1u32, 1_u32] }>(); // ok - - takes_array::<{ [N, N2, 1 + 1] }>(); // not implemented - //~^ ERROR complex const arguments must be placed inside of a `const` block - - takes_array::<{ [N; 3] }>(); // not implemented - //~^ ERROR complex const arguments must be placed inside of a `const` block -} - -fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr.stderr b/tests/ui/const-generics/mgca/array-expr.stderr deleted file mode 100644 index 0dda791c2e106..0000000000000 --- a/tests/ui/const-generics/mgca/array-expr.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: complex const arguments must be placed inside of a `const` block - --> $DIR/array-expr.rs:17:29 - | -LL | takes_array::<{ [N, N2, 1 + 1] }>(); // not implemented - | ^^^^^ - -error: complex const arguments must be placed inside of a `const` block - --> $DIR/array-expr.rs:20:19 - | -LL | takes_array::<{ [N; 3] }>(); // not implemented - | ^^^^^^^^^^ - -error: aborting due to 2 previous errors -