Skip to content

Commit c405e43

Browse files
committed
Use ConstArg for array lengths
1 parent 586600f commit c405e43

File tree

14 files changed

+62
-38
lines changed

14 files changed

+62
-38
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,10 +2345,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23452345
"using `_` for array lengths is unstable",
23462346
)
23472347
.stash(c.value.span, StashKey::UnderscoreForArrayLengths);
2348-
hir::ArrayLen::Body(self.lower_anon_const(c))
2348+
hir::ArrayLen::Body(self.lower_anon_const_as_const_arg(c))
23492349
}
23502350
}
2351-
_ => hir::ArrayLen::Body(self.lower_anon_const(c)),
2351+
_ => hir::ArrayLen::Body(self.lower_anon_const_as_const_arg(c)),
23522352
}
23532353
}
23542354

compiler/rustc_hir/src/hir.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,13 +1614,13 @@ pub type Lit = Spanned<LitKind>;
16141614
#[derive(Copy, Clone, Debug, HashStable_Generic)]
16151615
pub enum ArrayLen<'hir> {
16161616
Infer(InferArg),
1617-
Body(&'hir AnonConst),
1617+
Body(&'hir ConstArg<'hir>),
16181618
}
16191619

16201620
impl ArrayLen<'_> {
16211621
pub fn hir_id(&self) -> HirId {
16221622
match self {
1623-
ArrayLen::Infer(InferArg { hir_id, .. }) | ArrayLen::Body(AnonConst { hir_id, .. }) => {
1623+
ArrayLen::Infer(InferArg { hir_id, .. }) | ArrayLen::Body(ConstArg { hir_id, .. }) => {
16241624
*hir_id
16251625
}
16261626
}

compiler/rustc_hir/src/intravisit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen<'v>
710710
match len {
711711
// FIXME: Use `visit_infer` here.
712712
ArrayLen::Infer(InferArg { hir_id, span: _ }) => visitor.visit_id(*hir_id),
713-
ArrayLen::Body(c) => visitor.visit_anon_const(c),
713+
ArrayLen::Body(c) => visitor.visit_const_arg(c),
714714
}
715715
}
716716

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2147,7 +2147,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
21472147
let length = match length {
21482148
hir::ArrayLen::Infer(inf) => self.ct_infer(tcx.types.usize, None, inf.span),
21492149
hir::ArrayLen::Body(constant) => {
2150-
ty::Const::from_anon_const(tcx, constant.def_id)
2150+
ty::Const::from_const_arg_without_feeding(tcx, constant)
21512151
}
21522152
};
21532153

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ impl<'a> State<'a> {
975975
fn print_array_length(&mut self, len: &hir::ArrayLen<'_>) {
976976
match len {
977977
hir::ArrayLen::Infer(..) => self.word("_"),
978-
hir::ArrayLen::Body(ct) => self.print_anon_const(ct),
978+
hir::ArrayLen::Body(ct) => self.print_const_arg(ct),
979979
}
980980
}
981981

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1440,7 +1440,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14401440
return;
14411441
};
14421442
if let hir::TyKind::Array(_, length) = ty.peel_refs().kind
1443-
&& let hir::ArrayLen::Body(&hir::AnonConst { hir_id, .. }) = length
1443+
&& let hir::ArrayLen::Body(&hir::ConstArg { hir_id, .. }) = length
14441444
{
14451445
let span = self.tcx.hir().span(hir_id);
14461446
self.dcx().try_steal_modify_and_emit_err(

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
437437
pub fn lower_array_length(&self, length: &hir::ArrayLen<'tcx>) -> ty::Const<'tcx> {
438438
match length {
439439
hir::ArrayLen::Infer(inf) => self.ct_infer(self.tcx.types.usize, None, inf.span),
440-
hir::ArrayLen::Body(anon_const) => {
441-
let span = self.tcx.def_span(anon_const.def_id);
442-
let c = ty::Const::from_anon_const(self.tcx, anon_const.def_id);
440+
hir::ArrayLen::Body(const_arg) => {
441+
let span = const_arg.span();
442+
let c = ty::Const::from_const_arg_without_feeding(self.tcx, const_arg);
443443
self.register_wf_obligation(c.into(), span, ObligationCauseCode::WellFormed(None));
444444
self.normalize(span, c)
445445
}

compiler/rustc_infer/src/infer/error_reporting/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2189,7 +2189,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
21892189
};
21902190
if let Some(tykind) = tykind
21912191
&& let hir::TyKind::Array(_, length) = tykind
2192-
&& let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length
2192+
&& let hir::ArrayLen::Body(hir::ConstArg { hir_id, .. }) = length
21932193
{
21942194
let span = self.tcx.hir().span(*hir_id);
21952195
Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength { span, length: sz.found })

src/librustdoc/clean/mod.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,17 +1853,26 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
18531853
TyKind::Array(ty, ref length) => {
18541854
let length = match length {
18551855
hir::ArrayLen::Infer(..) => "_".to_string(),
1856-
hir::ArrayLen::Body(anon_const) => {
1856+
hir::ArrayLen::Body(const_arg) => {
18571857
// NOTE(min_const_generics): We can't use `const_eval_poly` for constants
18581858
// as we currently do not supply the parent generics to anonymous constants
18591859
// but do allow `ConstKind::Param`.
18601860
//
18611861
// `const_eval_poly` tries to first substitute generic parameters which
18621862
// results in an ICE while manually constructing the constant and using `eval`
18631863
// does nothing for `ConstKind::Param`.
1864-
let ct = ty::Const::from_anon_const(cx.tcx, anon_const.def_id);
1865-
let param_env = cx.tcx.param_env(anon_const.def_id);
1866-
print_const(cx, ct.normalize(cx.tcx, param_env))
1864+
let ct = ty::Const::from_const_arg_without_feeding(cx.tcx, const_arg);
1865+
let ct = if let hir::ConstArgKind::Anon(hir::AnonConst { def_id, .. }) =
1866+
const_arg.kind
1867+
{
1868+
// Only anon consts can implicitly capture params.
1869+
// FIXME: is this correct behavior?
1870+
let param_env = cx.tcx.param_env(*def_id);
1871+
ct.normalize(cx.tcx, param_env)
1872+
} else {
1873+
ct
1874+
};
1875+
print_const(cx, ct)
18671876
}
18681877
};
18691878

src/tools/clippy/clippy_lints/src/large_stack_arrays.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,12 @@ fn might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool {
106106
///
107107
/// This is a fail-safe to a case where even the `is_from_proc_macro` is unable to determain the
108108
/// correct result.
109-
fn repeat_expr_might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool {
110-
let ExprKind::Repeat(_, ArrayLen::Body(anon_const)) = expr.kind else {
109+
fn repeat_expr_might_be_expanded<'tcx>(expr: &Expr<'tcx>) -> bool {
110+
let ExprKind::Repeat(_, ArrayLen::Body(len_ct)) = expr.kind else {
111111
return false;
112112
};
113-
let len_span = cx.tcx.def_span(anon_const.def_id);
114-
!expr.span.contains(len_span)
113+
!expr.span.contains(len_ct.span())
115114
}
116115

117-
expr.span.from_expansion() || is_from_proc_macro(cx, expr) || repeat_expr_might_be_expanded(cx, expr)
116+
expr.span.from_expansion() || is_from_proc_macro(cx, expr) || repeat_expr_might_be_expanded(expr)
118117
}

src/tools/clippy/clippy_lints/src/trailing_empty_array.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,14 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray {
5353
}
5454
}
5555

56-
fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
56+
fn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool {
5757
if let ItemKind::Struct(data, _) = &item.kind
5858
// First check if last field is an array
5959
&& let Some(last_field) = data.fields().last()
6060
&& let rustc_hir::TyKind::Array(_, rustc_hir::ArrayLen::Body(length)) = last_field.ty.kind
6161

6262
// Then check if that array is zero-sized
63-
&& let length = Const::from_anon_const(cx.tcx, length.def_id)
63+
&& let length = Const::from_const_arg_without_feeding(cx.tcx, length)
6464
&& let length = length.try_eval_target_usize(cx.tcx, cx.param_env)
6565
&& let Some(length) = length
6666
{

src/tools/clippy/clippy_lints/src/utils/author.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ use clippy_utils::{get_attr, higher};
55
use rustc_ast::ast::{LitFloatType, LitKind};
66
use rustc_ast::LitIntType;
77
use rustc_data_structures::fx::FxHashMap;
8-
use rustc_hir as hir;
98
use rustc_hir::{
10-
ArrayLen, BindingMode, CaptureBy, Closure, ClosureKind, CoroutineKind, ExprKind, FnRetTy, HirId, Lit, PatKind,
11-
QPath, StmtKind, TyKind,
9+
self as hir, ArrayLen, BindingMode, CaptureBy, Closure, ClosureKind, ConstArg, ConstArgKind, CoroutineKind,
10+
ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind,
1211
};
1312
use rustc_lint::{LateContext, LateLintPass, LintContext};
1413
use rustc_session::declare_lint_pass;
@@ -270,6 +269,21 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
270269
}
271270
}
272271

272+
fn const_arg(&self, const_arg: &Binding<&ConstArg<'_>>) {
273+
match const_arg.value.kind {
274+
ConstArgKind::Path(ref qpath) => {
275+
bind!(self, qpath);
276+
chain!(self, "let ConstArgKind::Path(ref {qpath}) = {const_arg}.kind");
277+
self.qpath(qpath);
278+
},
279+
ConstArgKind::Anon(anon_const) => {
280+
bind!(self, anon_const);
281+
chain!(self, "let ConstArgKind::({anon_const}) = {const_arg}.kind");
282+
self.body(field!(anon_const.body));
283+
},
284+
}
285+
}
286+
273287
fn lit(&self, lit: &Binding<&Lit>) {
274288
let kind = |kind| chain!(self, "let LitKind::{kind} = {lit}.node");
275289
macro_rules! kind {
@@ -602,10 +616,10 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
602616
self.expr(value);
603617
match length.value {
604618
ArrayLen::Infer(..) => chain!(self, "let ArrayLen::Infer(..) = length"),
605-
ArrayLen::Body(anon_const) => {
606-
bind!(self, anon_const);
607-
chain!(self, "let ArrayLen::Body({anon_const}) = {length}");
608-
self.body(field!(anon_const.body));
619+
ArrayLen::Body(const_arg) => {
620+
bind!(self, const_arg);
621+
chain!(self, "let ArrayLen::Body({const_arg}) = {length}");
622+
self.const_arg(const_arg);
609623
},
610624
}
611625
},

src/tools/clippy/clippy_utils/src/hir_utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ impl HirEqInterExpr<'_, '_, '_> {
227227
pub fn eq_array_length(&mut self, left: ArrayLen<'_>, right: ArrayLen<'_>) -> bool {
228228
match (left, right) {
229229
(ArrayLen::Infer(..), ArrayLen::Infer(..)) => true,
230-
(ArrayLen::Body(l_ct), ArrayLen::Body(r_ct)) => self.eq_body(l_ct.body, r_ct.body),
230+
(ArrayLen::Body(l_ct), ArrayLen::Body(r_ct)) => self.eq_const_arg(l_ct, r_ct),
231231
(_, _) => false,
232232
}
233233
}
@@ -1134,7 +1134,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
11341134
pub fn hash_array_length(&mut self, length: ArrayLen<'_>) {
11351135
match length {
11361136
ArrayLen::Infer(..) => {},
1137-
ArrayLen::Body(anon_const) => self.hash_body(anon_const.body),
1137+
ArrayLen::Body(ct) => self.hash_const_arg(ct),
11381138
}
11391139
}
11401140

src/tools/clippy/clippy_utils/src/lib.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ use rustc_hir::hir_id::{HirIdMap, HirIdSet};
100100
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
101101
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
102102
use rustc_hir::{
103-
self as hir, def, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, Destination, Expr,
104-
ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, Item,
105-
ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, PathSegment,
106-
PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp,
103+
self as hir, def, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind,
104+
Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind,
105+
ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path,
106+
PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp,
107107
};
108108
use rustc_lexer::{tokenize, TokenKind};
109109
use rustc_lint::{LateContext, Level, Lint, LintContext};
@@ -871,7 +871,8 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
871871
},
872872
ExprKind::Tup(items) | ExprKind::Array(items) => items.iter().all(|x| is_default_equivalent(cx, x)),
873873
ExprKind::Repeat(x, ArrayLen::Body(len)) => {
874-
if let ExprKind::Lit(const_lit) = cx.tcx.hir().body(len.body).value.kind
874+
if let ConstArgKind::Anon(anon_const) = len.kind
875+
&& let ExprKind::Lit(const_lit) = cx.tcx.hir().body(anon_const.body).value.kind
875876
&& let LitKind::Int(v, _) = const_lit.node
876877
&& v <= 32
877878
&& is_default_equivalent(cx, x)
@@ -900,7 +901,8 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: &
900901
}) => return sym.is_empty() && is_path_lang_item(cx, ty, LangItem::String),
901902
ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec),
902903
ExprKind::Repeat(_, ArrayLen::Body(len)) => {
903-
if let ExprKind::Lit(const_lit) = cx.tcx.hir().body(len.body).value.kind
904+
if let ConstArgKind::Anon(anon_const) = len.kind
905+
&& let ExprKind::Lit(const_lit) = cx.tcx.hir().body(anon_const.body).value.kind
904906
&& let LitKind::Int(v, _) = const_lit.node
905907
{
906908
return v == 0 && is_path_diagnostic_item(cx, ty, sym::Vec);

0 commit comments

Comments
 (0)