about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorDominik Stolz <d.stolz@tum.de>2024-11-28 17:33:22 +0100
committerDominik Stolz <d.stolz@tum.de>2024-11-30 21:00:31 +0100
commitd38f01312c1b827a7a0186c186482579a82cdec3 (patch)
tree7eef9e12f4799d651da2054c1817c1731019b689 /compiler
parent9b4d7c6a40b328d212095c28670c629facf1557d (diff)
downloadrust-d38f01312c1b827a7a0186c186482579a82cdec3.tar.gz
rust-d38f01312c1b827a7a0186c186482579a82cdec3.zip
Remove hir::ArrayLen, introduce ConstArgKind::Infer
Remove Node::ArrayLenInfer
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs13
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs19
-rw-r--r--compiler/rustc_hir/src/hir.rs47
-rw-r--r--compiler/rustc_hir/src/intravisit.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs9
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs18
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs4
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs3
16 files changed, 59 insertions, 119 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 3af29838b72..a65cfec2713 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -118,7 +118,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 }
                 ExprKind::Repeat(expr, count) => {
                     let expr = self.lower_expr(expr);
-                    let count = self.lower_array_length(count);
+                    let count = self.lower_array_length_to_const_arg(count);
                     hir::ExprKind::Repeat(expr, count)
                 }
                 ExprKind::Tup(elts) => hir::ExprKind::Tup(self.lower_exprs(elts)),
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index 65e387de800..c3ff7b4b897 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -235,8 +235,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     }
 
     fn visit_anon_const(&mut self, constant: &'hir AnonConst) {
-        // FIXME: use real span?
-        self.insert(DUMMY_SP, constant.hir_id, Node::AnonConst(constant));
+        self.insert(constant.span, constant.hir_id, Node::AnonConst(constant));
 
         self.with_parent(constant.hir_id, |this| {
             intravisit::walk_anon_const(this, constant);
@@ -252,8 +251,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     }
 
     fn visit_const_arg(&mut self, const_arg: &'hir ConstArg<'hir>) {
-        // FIXME: use real span?
-        self.insert(DUMMY_SP, const_arg.hir_id, Node::ConstArg(const_arg));
+        self.insert(const_arg.span(), const_arg.hir_id, Node::ConstArg(const_arg));
 
         self.with_parent(const_arg.hir_id, |this| {
             intravisit::walk_const_arg(this, const_arg);
@@ -387,13 +385,6 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         });
     }
 
-    fn visit_array_length(&mut self, len: &'hir ArrayLen<'hir>) {
-        match len {
-            ArrayLen::Infer(inf) => self.insert(inf.span, inf.hir_id, Node::ArrayLenInfer(inf)),
-            ArrayLen::Body(..) => intravisit::walk_array_len(self, len),
-        }
-    }
-
     fn visit_pattern_type_pattern(&mut self, p: &'hir hir::Pat<'hir>) {
         self.visit_pat(p)
     }
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index dae816663e0..660a80ee622 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1277,9 +1277,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     }),
                 ))
             }
-            TyKind::Array(ty, length) => {
-                hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_array_length(length))
-            }
+            TyKind::Array(ty, length) => hir::TyKind::Array(
+                self.lower_ty(ty, itctx),
+                self.lower_array_length_to_const_arg(length),
+            ),
             TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const_to_anon_const(expr)),
             TyKind::TraitObject(bounds, kind) => {
                 let mut lifetime_bound = None;
@@ -2029,14 +2030,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.expr_block(block)
     }
 
-    fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen<'hir> {
+    fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
         match c.value.kind {
             ExprKind::Underscore => {
                 if self.tcx.features().generic_arg_infer() {
-                    hir::ArrayLen::Infer(hir::InferArg {
-                        hir_id: self.lower_node_id(c.id),
-                        span: self.lower_span(c.value.span),
-                    })
+                    let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span));
+                    self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
                 } else {
                     feature_err(
                         &self.tcx.sess,
@@ -2045,10 +2044,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         fluent_generated::ast_lowering_underscore_array_length_unstable,
                     )
                     .stash(c.value.span, StashKey::UnderscoreForArrayLengths);
-                    hir::ArrayLen::Body(self.lower_anon_const_to_const_arg(c))
+                    self.lower_anon_const_to_const_arg(c)
                 }
             }
-            _ => hir::ArrayLen::Body(self.lower_anon_const_to_const_arg(c)),
+            _ => self.lower_anon_const_to_const_arg(c),
         }
     }
 
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 12dec75e65c..97aa88c1de8 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -275,6 +275,7 @@ impl<'hir> ConstArg<'hir> {
         match self.kind {
             ConstArgKind::Path(path) => path.span(),
             ConstArgKind::Anon(anon) => anon.span,
+            ConstArgKind::Infer(span) => span,
         }
     }
 }
@@ -289,6 +290,11 @@ pub enum ConstArgKind<'hir> {
     /// However, in the future, we'll be using it for all of those.
     Path(QPath<'hir>),
     Anon(&'hir AnonConst),
+    /// **Note:** Not all inferred consts are represented as
+    /// `ConstArgKind::Infer`. In cases where it is ambiguous whether
+    /// a generic arg is a type or a const, inference variables are
+    /// represented as `GenericArg::Infer` instead.
+    Infer(Span),
 }
 
 #[derive(Clone, Copy, Debug, HashStable_Generic)]
@@ -308,6 +314,10 @@ pub enum GenericArg<'hir> {
     Lifetime(&'hir Lifetime),
     Type(&'hir Ty<'hir>),
     Const(&'hir ConstArg<'hir>),
+    /// **Note:** Inference variables are only represented as
+    /// `GenericArg::Infer` in cases where it is ambiguous whether
+    /// a generic arg is a type or a const. Otherwise, inference variables
+    /// are represented as `TyKind::Infer` or `ConstArgKind::Infer`.
     Infer(InferArg),
 }
 
@@ -1645,29 +1655,6 @@ impl fmt::Display for ConstContext {
 /// A literal.
 pub type Lit = Spanned<LitKind>;
 
-#[derive(Copy, Clone, Debug, HashStable_Generic)]
-pub enum ArrayLen<'hir> {
-    Infer(InferArg),
-    Body(&'hir ConstArg<'hir>),
-}
-
-impl ArrayLen<'_> {
-    pub fn span(self) -> Span {
-        match self {
-            ArrayLen::Infer(arg) => arg.span,
-            ArrayLen::Body(body) => body.span(),
-        }
-    }
-
-    pub fn hir_id(self) -> HirId {
-        match self {
-            ArrayLen::Infer(InferArg { hir_id, .. }) | ArrayLen::Body(&ConstArg { hir_id, .. }) => {
-                hir_id
-            }
-        }
-    }
-}
-
 /// A constant (expression) that's not an item or associated item,
 /// but needs its own `DefId` for type-checking, const-eval, etc.
 /// These are usually found nested inside types (e.g., array lengths)
@@ -2115,7 +2102,7 @@ pub enum ExprKind<'hir> {
     ///
     /// E.g., `[1; 5]`. The first expression is the element
     /// to be repeated; the second is the number of times to repeat it.
-    Repeat(&'hir Expr<'hir>, ArrayLen<'hir>),
+    Repeat(&'hir Expr<'hir>, &'hir ConstArg<'hir>),
 
     /// A suspension point for coroutines (i.e., `yield <expr>`).
     Yield(&'hir Expr<'hir>, YieldSource),
@@ -2625,7 +2612,7 @@ impl<'hir> Ty<'hir> {
             TyKind::Infer => true,
             TyKind::Slice(ty) => ty.is_suggestable_infer_ty(),
             TyKind::Array(ty, length) => {
-                ty.is_suggestable_infer_ty() || matches!(length, ArrayLen::Infer(..))
+                ty.is_suggestable_infer_ty() || matches!(length.kind, ConstArgKind::Infer(..))
             }
             TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty),
             TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(),
@@ -2834,7 +2821,7 @@ pub enum TyKind<'hir> {
     /// A variable length slice (i.e., `[T]`).
     Slice(&'hir Ty<'hir>),
     /// A fixed length array (i.e., `[T; n]`).
-    Array(&'hir Ty<'hir>, ArrayLen<'hir>),
+    Array(&'hir Ty<'hir>, &'hir ConstArg<'hir>),
     /// A raw pointer (i.e., `*const T` or `*mut T`).
     Ptr(MutTy<'hir>),
     /// A reference (i.e., `&'a T` or `&'a mut T`).
@@ -2861,6 +2848,11 @@ pub enum TyKind<'hir> {
     Typeof(&'hir AnonConst),
     /// `TyKind::Infer` means the type should be inferred instead of it having been
     /// specified. This can appear anywhere in a type.
+    ///
+    /// **Note:** Not all inferred types are represented as
+    /// `TyKind::Infer`. In cases where it is ambiguous whether
+    /// a generic arg is a type or a const, inference variables are
+    /// represented as `GenericArg::Infer` instead.
     Infer,
     /// Placeholder for a type that has failed to be defined.
     Err(rustc_span::ErrorGuaranteed),
@@ -3801,8 +3793,6 @@ pub enum Node<'hir> {
     Crate(&'hir Mod<'hir>),
     Infer(&'hir InferArg),
     WherePredicate(&'hir WherePredicate<'hir>),
-    // FIXME: Merge into `Node::Infer`.
-    ArrayLenInfer(&'hir InferArg),
     PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
     // Created by query feeding
     Synthetic,
@@ -3856,7 +3846,6 @@ impl<'hir> Node<'hir> {
             | Node::OpaqueTy(..)
             | Node::Infer(..)
             | Node::WherePredicate(..)
-            | Node::ArrayLenInfer(..)
             | Node::Synthetic
             | Node::Err(..) => None,
         }
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index faaea41047f..602aa8be740 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -343,9 +343,6 @@ pub trait Visitor<'v>: Sized {
     fn visit_pat_field(&mut self, f: &'v PatField<'v>) -> Self::Result {
         walk_pat_field(self, f)
     }
-    fn visit_array_length(&mut self, len: &'v ArrayLen<'v>) -> Self::Result {
-        walk_array_len(self, len)
-    }
     fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result {
         walk_anon_const(self, c)
     }
@@ -710,14 +707,6 @@ pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'
     visitor.visit_pat(field.pat)
 }
 
-pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen<'v>) -> V::Result {
-    match len {
-        // FIXME: Use `visit_infer` here.
-        ArrayLen::Infer(InferArg { hir_id, span: _ }) => visitor.visit_id(*hir_id),
-        ArrayLen::Body(c) => visitor.visit_const_arg(c),
-    }
-}
-
 pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) -> V::Result {
     try_visit!(visitor.visit_id(constant.hir_id));
     visitor.visit_nested_body(constant.body)
@@ -739,6 +728,7 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>(
     match &const_arg.kind {
         ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, const_arg.hir_id, qpath.span()),
         ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon),
+        ConstArgKind::Infer(..) => V::Result::output(),
     }
 }
 
@@ -753,7 +743,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
         }
         ExprKind::Repeat(ref element, ref count) => {
             try_visit!(visitor.visit_expr(element));
-            try_visit!(visitor.visit_array_length(count));
+            try_visit!(visitor.visit_const_arg(count));
         }
         ExprKind::Struct(ref qpath, fields, ref optional_base) => {
             try_visit!(visitor.visit_qpath(qpath, expression.hir_id, expression.span));
@@ -901,7 +891,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
         }
         TyKind::Array(ref ty, ref length) => {
             try_visit!(visitor.visit_ty(ty));
-            try_visit!(visitor.visit_array_length(length));
+            try_visit!(visitor.visit_const_arg(length));
         }
         TyKind::TraitObject(bounds, ref lifetime, _syntax) => {
             for bound in bounds {
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 93be3e06e5d..7bc1827098b 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -150,11 +150,11 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector {
             _ => {}
         }
     }
-    fn visit_array_length(&mut self, length: &'v hir::ArrayLen<'v>) {
-        if let hir::ArrayLen::Infer(inf) = length {
-            self.0.push(inf.span);
+    fn visit_const_arg(&mut self, const_arg: &'v hir::ConstArg<'v>) {
+        if let hir::ConstArgKind::Infer(span) = const_arg.kind {
+            self.0.push(span);
         }
-        intravisit::walk_array_len(self, length)
+        intravisit::walk_const_arg(self, const_arg)
     }
 }
 
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index c31bff28fd3..077696ac1f2 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -181,7 +181,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                     // expressions' count (i.e. `N` in `[x; N]`), and explicit
                     // `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`),
                     // as they shouldn't be able to cause query cycle errors.
-                    Node::Expr(Expr { kind: ExprKind::Repeat(_, ArrayLen::Body(ct)), .. })
+                    Node::Expr(Expr { kind: ExprKind::Repeat(_, ct), .. })
                         if ct.anon_const_hir_id() == Some(hir_id) =>
                     {
                         Some(parent_did)
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 816761fd00f..e07fdc98e78 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -144,7 +144,7 @@ fn const_arg_anon_type_of<'tcx>(tcx: TyCtxt<'tcx>, arg_hir_id: HirId, span: Span
         // Easy case: arrays repeat expressions.
         Node::Ty(&hir::Ty { kind: TyKind::Array(_, ref constant), .. })
         | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
-            if constant.hir_id() == arg_hir_id =>
+            if constant.hir_id == arg_hir_id =>
         {
             return tcx.types.usize;
         }
@@ -578,8 +578,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
             x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
         },
 
-        Node::ArrayLenInfer(_) => tcx.types.usize,
-
         x => {
             bug!("unexpected sort of node in type_of(): {:?}", x);
         }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
index ae1279d428c..c3f4fc8699a 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
@@ -104,7 +104,7 @@ fn generic_arg_mismatch_err(
             GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }),
             GenericParamDefKind::Const { .. },
         ) if tcx.type_of(param.def_id).skip_binder() == tcx.types.usize => {
-            let snippet = sess.source_map().span_to_snippet(tcx.hir().span(len.hir_id()));
+            let snippet = sess.source_map().span_to_snippet(tcx.hir().span(len.hir_id));
             if let Ok(snippet) = snippet {
                 err.span_suggestion(
                     arg.span(),
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 01276abec22..ecfbbd697b7 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -2089,6 +2089,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 format!("Const::lower_const_arg: invalid qpath {qpath:?}"),
             ),
             hir::ConstArgKind::Anon(anon) => Const::from_anon_const(tcx, anon.def_id),
+            hir::ConstArgKind::Infer(span) => self.ct_infer(None, span),
         }
     }
 
@@ -2309,13 +2310,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 tcx.at(span).type_of(def_id).instantiate(tcx, args)
             }
             hir::TyKind::Array(ty, length) => {
-                let length = match length {
-                    hir::ArrayLen::Infer(inf) => self.ct_infer(None, inf.span),
-                    hir::ArrayLen::Body(constant) => {
-                        self.lower_const_arg(constant, FeedConstTy::No)
-                    }
-                };
-
+                let length = self.lower_const_arg(length, FeedConstTy::No);
                 Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length)
             }
             hir::TyKind::Typeof(e) => tcx.type_of(e.def_id).instantiate_identity(),
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 64c6969d4b9..bba1dff0243 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -118,7 +118,6 @@ impl<'a> State<'a> {
             Node::LetStmt(a) => self.print_local_decl(a),
             Node::Crate(..) => panic!("cannot print Crate"),
             Node::WherePredicate(pred) => self.print_where_predicate(pred),
-            Node::ArrayLenInfer(_) => self.word("_"),
             Node::Synthetic => unreachable!(),
             Node::Err(_) => self.word("/*ERROR*/"),
         }
@@ -315,7 +314,7 @@ impl<'a> State<'a> {
                 self.word("[");
                 self.print_type(ty);
                 self.word("; ");
-                self.print_array_length(length);
+                self.print_const_arg(length);
                 self.word("]");
             }
             hir::TyKind::Typeof(ref e) => {
@@ -986,13 +985,6 @@ impl<'a> State<'a> {
         self.print_else(elseopt)
     }
 
-    fn print_array_length(&mut self, len: &hir::ArrayLen<'_>) {
-        match len {
-            hir::ArrayLen::Infer(..) => self.word("_"),
-            hir::ArrayLen::Body(ct) => self.print_const_arg(ct),
-        }
-    }
-
     fn print_anon_const(&mut self, constant: &hir::AnonConst) {
         self.ann.nested(self, Nested::Body(constant.body))
     }
@@ -1001,6 +993,7 @@ impl<'a> State<'a> {
         match &const_arg.kind {
             ConstArgKind::Path(qpath) => self.print_qpath(qpath, true),
             ConstArgKind::Anon(anon) => self.print_anon_const(anon),
+            ConstArgKind::Infer(..) => self.word("_"),
         }
     }
 
@@ -1077,12 +1070,12 @@ impl<'a> State<'a> {
         self.end()
     }
 
-    fn print_expr_repeat(&mut self, element: &hir::Expr<'_>, count: &hir::ArrayLen<'_>) {
+    fn print_expr_repeat(&mut self, element: &hir::Expr<'_>, count: &hir::ConstArg<'_>) {
         self.ibox(INDENT_UNIT);
         self.word("[");
         self.print_expr(element);
         self.word_space(";");
-        self.print_array_length(count);
+        self.print_const_arg(count);
         self.word("]");
         self.end()
     }
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index b4715839cf5..4699b342cec 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -19,7 +19,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{ExprKind, HirId, QPath};
-use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _;
+use rustc_hir_analysis::hir_ty_lowering::{FeedConstTy, HirTyLowerer as _};
 use rustc_infer::infer;
 use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
 use rustc_infer::traits::ObligationCause;
@@ -425,7 +425,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             | hir::Node::Crate(_)
             | hir::Node::Infer(_)
             | hir::Node::WherePredicate(_)
-            | hir::Node::ArrayLenInfer(_)
             | hir::Node::PreciseCapturingNonLifetimeArg(_)
             | hir::Node::OpaqueTy(_) => {
                 unreachable!("no sub-expr expected for {parent_node:?}")
@@ -1673,9 +1672,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         else {
             return;
         };
-        if let hir::TyKind::Array(_, length) = ty.peel_refs().kind
-            && let hir::ArrayLen::Body(ct) = length
-        {
+        if let hir::TyKind::Array(_, ct) = ty.peel_refs().kind {
             let span = ct.span();
             self.dcx().try_steal_modify_and_emit_err(
                 span,
@@ -1713,13 +1710,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_expr_repeat(
         &self,
         element: &'tcx hir::Expr<'tcx>,
-        count: &'tcx hir::ArrayLen<'tcx>,
+        count: &'tcx hir::ConstArg<'tcx>,
         expected: Expectation<'tcx>,
         expr: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
         let count_span = count.span();
-        let count = self.try_structurally_resolve_const(count_span, self.lower_array_length(count));
+        let count = self.try_structurally_resolve_const(
+            count_span,
+            self.normalize(count_span, self.lower_const_arg(count, FeedConstTy::No)),
+        );
 
         if let Some(count) = count.try_to_target_usize(tcx) {
             self.suggest_array_len(expr, count);
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 47af8c681da..753fc39b0e9 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -486,24 +486,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub(crate) fn lower_array_length(&self, length: &hir::ArrayLen<'tcx>) -> ty::Const<'tcx> {
-        match length {
-            hir::ArrayLen::Infer(inf) => self.ct_infer(None, inf.span),
-            hir::ArrayLen::Body(const_arg) => {
-                let span = const_arg.span();
-                let c = self.lowerer().lower_const_arg(const_arg, FeedConstTy::No);
-                self.register_wf_obligation(c.into(), span, ObligationCauseCode::WellFormed(None));
-                self.normalize(span, c)
-            }
-        }
-    }
-
     pub(crate) fn lower_const_arg(
         &self,
         const_arg: &'tcx hir::ConstArg<'tcx>,
-        param_def_id: DefId,
+        feed: FeedConstTy,
     ) -> ty::Const<'tcx> {
-        let ct = self.lowerer().lower_const_arg(const_arg, FeedConstTy::Param(param_def_id));
+        let ct = self.lowerer().lower_const_arg(const_arg, feed);
         self.register_wf_obligation(
             ct.into(),
             self.tcx.hir().span(const_arg.hir_id),
@@ -1278,7 +1266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         self.fcx.lower_ty(ty).raw.into()
                     }
                     (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
-                        self.fcx.lower_const_arg(ct, param.def_id).into()
+                        self.fcx.lower_const_arg(ct, FeedConstTy::Param(param.def_id)).into()
                     }
                     (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => {
                         self.fcx.ty_infer(Some(param), inf.span).into()
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index 3754fd02428..b31ee1a55d6 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -7,7 +7,7 @@ use rustc_hir_analysis::hir_ty_lowering::generics::{
     check_generic_arg_count_for_call, lower_generic_args,
 };
 use rustc_hir_analysis::hir_ty_lowering::{
-    GenericArgsLowerer, HirTyLowerer, IsMethodCall, RegionInferReason,
+    FeedConstTy, GenericArgsLowerer, HirTyLowerer, IsMethodCall, RegionInferReason,
 };
 use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk};
 use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
@@ -429,7 +429,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                         self.cfcx.lower_ty(ty).raw.into()
                     }
                     (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
-                        self.cfcx.lower_const_arg(ct, param.def_id).into()
+                        self.cfcx.lower_const_arg(ct, FeedConstTy::Param(param.def_id)).into()
                     }
                     (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => {
                         self.cfcx.ty_infer(Some(param), inf.span).into()
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 4900575c36e..0c701c834f2 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -948,7 +948,6 @@ impl<'hir> Map<'hir> {
             Node::LetStmt(local) => local.span,
             Node::Crate(item) => item.spans.inner_span,
             Node::WherePredicate(pred) => pred.span,
-            Node::ArrayLenInfer(inf) => inf.span,
             Node::PreciseCapturingNonLifetimeArg(param) => param.ident.span,
             Node::Synthetic => unreachable!(),
             Node::Err(span) => span,
@@ -1226,7 +1225,6 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
         }
         Node::Crate(..) => String::from("(root_crate)"),
         Node::WherePredicate(_) => node_str("where predicate"),
-        Node::ArrayLenInfer(_) => node_str("array len infer"),
         Node::Synthetic => unreachable!(),
         Node::Err(_) => node_str("error"),
         Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"),
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index 0f9d4cb1982..8ba7969207e 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -1837,11 +1837,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         };
         if let Some(tykind) = tykind
             && let hir::TyKind::Array(_, length) = tykind
-            && let hir::ArrayLen::Body(ct) = length
             && let Some((scalar, ty)) = sz.found.try_to_scalar()
             && ty == self.tcx.types.usize
         {
-            let span = ct.span();
+            let span = length.span();
             Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength {
                 span,
                 length: scalar.to_target_usize(&self.tcx).unwrap(),