Skip to content

Commit d79ca2d

Browse files
committed
ast->hir and astconv for array lengths
1 parent 603f391 commit d79ca2d

File tree

11 files changed

+108
-86
lines changed

11 files changed

+108
-86
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
7777
}
7878
ExprKind::Repeat(expr, count) => {
7979
let expr = self.lower_expr(expr);
80-
let count = self.lower_array_length(count);
80+
let count = self.lower_array_length(
81+
count,
82+
&ImplTraitContext::Disallowed(ImplTraitPosition::RepeatExprs),
83+
);
8184
hir::ExprKind::Repeat(expr, count)
8285
}
8386
ExprKind::Tup(elts) => hir::ExprKind::Tup(self.lower_exprs(elts)),

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ enum ImplTraitContext {
257257
/// Position in which `impl Trait` is disallowed.
258258
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
259259
enum ImplTraitPosition {
260+
RepeatExprs,
260261
Path,
261262
Variable,
262263
Trait,
@@ -288,6 +289,7 @@ enum ImplTraitPosition {
288289
impl std::fmt::Display for ImplTraitPosition {
289290
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
290291
let name = match self {
292+
ImplTraitPosition::RepeatExprs => "repeat expr lengths",
291293
ImplTraitPosition::Path => "paths",
292294
ImplTraitPosition::Variable => "variable bindings",
293295
ImplTraitPosition::Trait => "traits",
@@ -1363,7 +1365,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13631365
))
13641366
}
13651367
TyKind::Array(ty, length) => {
1366-
hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_array_length(length))
1368+
hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_array_length(length, itctx))
13671369
}
13681370
TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)),
13691371
TyKind::TraitObject(bounds, kind) => {
@@ -2392,12 +2394,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23922394
self.expr_block(block)
23932395
}
23942396

2395-
fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen {
2396-
// FIXME(const_arg_kind)
2397-
match c.value.kind {
2397+
fn lower_array_length(
2398+
&mut self,
2399+
c: &AnonConst,
2400+
itctx: &ImplTraitContext,
2401+
) -> &'hir hir::ConstArg<'hir> {
2402+
let const_arg = match c.value.kind {
23982403
ExprKind::Underscore => {
23992404
if self.tcx.features().generic_arg_infer {
2400-
hir::ArrayLen::Infer(self.lower_node_id(c.id), c.value.span)
2405+
hir::ConstArg {
2406+
kind: hir::ConstArgKind::Infer(self.lower_node_id(c.id), c.value.span),
2407+
}
24012408
} else {
24022409
feature_err(
24032410
&self.tcx.sess.parse_sess,
@@ -2406,11 +2413,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
24062413
"using `_` for array lengths is unstable",
24072414
)
24082415
.stash(c.value.span, StashKey::UnderscoreForArrayLengths);
2409-
hir::ArrayLen::Body(self.lower_anon_const(c))
2416+
hir::ConstArg {
2417+
kind: hir::ConstArgKind::AnonConst(c.value.span, self.lower_anon_const(c)),
2418+
}
24102419
}
24112420
}
2412-
_ => hir::ArrayLen::Body(self.lower_anon_const(c)),
2413-
}
2421+
_ => return self.lower_const_arg(c, itctx),
2422+
};
2423+
self.arena.alloc(const_arg)
24142424
}
24152425

24162426
fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {

compiler/rustc_hir/src/hir.rs

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -250,20 +250,23 @@ pub struct ConstArg<'hir> {
250250
pub enum ConstArgKind<'hir> {
251251
AnonConst(Span, AnonConst),
252252
Param(HirId, QPath<'hir>),
253+
Infer(HirId, Span),
253254
}
254255

255256
impl<'hir> ConstArg<'hir> {
256257
pub fn span(&self) -> Span {
257258
match self.kind {
258259
ConstArgKind::AnonConst(span, _) => span,
259260
ConstArgKind::Param(_, qpath) => qpath.span(),
261+
ConstArgKind::Infer(_, span) => span,
260262
}
261263
}
262264

263265
pub fn hir_id(&self) -> HirId {
264266
match self.kind {
265267
ConstArgKind::AnonConst(_, ct) => ct.hir_id,
266268
ConstArgKind::Param(id, _) => id,
269+
ConstArgKind::Infer(id, _) => id,
267270
}
268271
}
269272
}
@@ -1667,20 +1670,6 @@ impl fmt::Display for ConstContext {
16671670
/// A literal.
16681671
pub type Lit = Spanned<LitKind>;
16691672

1670-
#[derive(Copy, Clone, Debug, HashStable_Generic)]
1671-
pub enum ArrayLen {
1672-
Infer(HirId, Span),
1673-
Body(AnonConst),
1674-
}
1675-
1676-
impl ArrayLen {
1677-
pub fn hir_id(&self) -> HirId {
1678-
match self {
1679-
&ArrayLen::Infer(hir_id, _) | &ArrayLen::Body(AnonConst { hir_id, .. }) => hir_id,
1680-
}
1681-
}
1682-
}
1683-
16841673
/// A constant (expression) that's not an item or associated item,
16851674
/// but needs its own `DefId` for type-checking, const-eval, etc.
16861675
/// These are usually found nested inside types (e.g., array lengths)
@@ -2055,7 +2044,7 @@ pub enum ExprKind<'hir> {
20552044
///
20562045
/// E.g., `[1; 5]`. The first expression is the element
20572046
/// to be repeated; the second is the number of times to repeat it.
2058-
Repeat(&'hir Expr<'hir>, ArrayLen),
2047+
Repeat(&'hir Expr<'hir>, &'hir ConstArg<'hir>),
20592048

20602049
/// A suspension point for generators (i.e., `yield <expr>`).
20612050
Yield(&'hir Expr<'hir>, YieldSource),
@@ -2692,7 +2681,7 @@ pub enum TyKind<'hir> {
26922681
/// A variable length slice (i.e., `[T]`).
26932682
Slice(&'hir Ty<'hir>),
26942683
/// A fixed length array (i.e., `[T; n]`).
2695-
Array(&'hir Ty<'hir>, ArrayLen),
2684+
Array(&'hir Ty<'hir>, &'hir ConstArg<'hir>),
26962685
/// A raw pointer (i.e., `*const T` or `*mut T`).
26972686
Ptr(MutTy<'hir>),
26982687
/// A reference (i.e., `&'a T` or `&'a mut T`).
@@ -3778,7 +3767,10 @@ impl<'hir> Node<'hir> {
37783767
kind:
37793768
ExprKind::ConstBlock(AnonConst { body, .. })
37803769
| ExprKind::Closure(Closure { body, .. })
3781-
| ExprKind::Repeat(_, ArrayLen::Body(AnonConst { body, .. })),
3770+
| ExprKind::Repeat(
3771+
_,
3772+
ConstArg { kind: ConstArgKind::AnonConst(_, AnonConst { body, .. }) },
3773+
),
37823774
..
37833775
}) => Some(*body),
37843776
_ => None,

compiler/rustc_hir/src/intravisit.rs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,6 @@ pub trait Visitor<'v>: Sized {
329329
fn visit_pat_field(&mut self, f: &'v PatField<'v>) {
330330
walk_pat_field(self, f)
331331
}
332-
fn visit_array_length(&mut self, len: &'v ArrayLen) {
333-
walk_array_len(self, len)
334-
}
335332
fn visit_anon_const(&mut self, c: &'v AnonConst) {
336333
walk_anon_const(self, c)
337334
}
@@ -670,13 +667,6 @@ pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'
670667
visitor.visit_pat(field.pat)
671668
}
672669

673-
pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen) {
674-
match len {
675-
&ArrayLen::Infer(hir_id, _span) => visitor.visit_id(hir_id),
676-
ArrayLen::Body(c) => visitor.visit_anon_const(c),
677-
}
678-
}
679-
680670
pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) {
681671
visitor.visit_id(constant.hir_id);
682672
visitor.visit_nested_body(constant.body);
@@ -691,7 +681,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
691681
ExprKind::ConstBlock(ref anon_const) => visitor.visit_anon_const(anon_const),
692682
ExprKind::Repeat(ref element, ref count) => {
693683
visitor.visit_expr(element);
694-
visitor.visit_array_length(count)
684+
visitor.visit_const_arg(count);
695685
}
696686
ExprKind::Struct(ref qpath, fields, ref optional_base) => {
697687
visitor.visit_qpath(qpath, expression.hir_id, expression.span);
@@ -841,7 +831,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
841831
}
842832
TyKind::Array(ref ty, ref length) => {
843833
visitor.visit_ty(ty);
844-
visitor.visit_array_length(length)
834+
visitor.visit_const_arg(length);
845835
}
846836
TyKind::TraitObject(bounds, ref lifetime, _syntax) => {
847837
for bound in bounds {
@@ -863,6 +853,9 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>(visitor: &mut V, ct: &'v ConstArg<'v>)
863853
visitor.visit_id(*hir_id);
864854
visitor.visit_qpath(qpath, *hir_id, qpath.span())
865855
}
856+
ConstArgKind::Infer(hir_id, _) => {
857+
visitor.visit_id(*hir_id);
858+
}
866859
}
867860
}
868861

compiler/rustc_hir_analysis/src/astconv/mod.rs

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,27 @@ pub struct PathSeg(pub DefId, pub usize);
6262
#[derive(Copy, Clone, Debug)]
6363
pub struct OnlySelfBounds(pub bool);
6464

65+
#[derive(Debug, Copy, Clone)]
66+
pub enum ConstArgsParam {
67+
Param(DefId),
68+
ArrayLen,
69+
}
70+
71+
impl From<DefId> for ConstArgsParam {
72+
fn from(value: DefId) -> Self {
73+
Self::Param(value)
74+
}
75+
}
76+
77+
impl ConstArgsParam {
78+
pub fn to_ty<'tcx>(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<Ty<'tcx>> {
79+
match self {
80+
ConstArgsParam::Param(param_def_id) => tcx.type_of(param_def_id),
81+
ConstArgsParam::ArrayLen => ty::EarlyBinder(tcx.types.usize),
82+
}
83+
}
84+
}
85+
6586
pub trait AstConv<'tcx> {
6687
fn tcx(&self) -> TyCtxt<'tcx>;
6788

@@ -3327,12 +3348,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
33273348
tcx.at(span).type_of(def_id).subst(tcx, substs)
33283349
}
33293350
hir::TyKind::Array(ty, length) => {
3330-
let length = match length {
3331-
&hir::ArrayLen::Infer(_, span) => self.ct_infer(tcx.types.usize, None, span),
3332-
hir::ArrayLen::Body(constant) => {
3333-
ty::Const::from_anon_const(tcx, constant.def_id)
3334-
}
3335-
};
3351+
let length = self.ast_const_to_const(length, ConstArgsParam::ArrayLen);
33363352

33373353
tcx.mk_array_with_const_len(self.ast_ty_to_ty(ty), length)
33383354
}
@@ -3755,17 +3771,28 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
37553771
}
37563772
}
37573773

3758-
#[instrument(level = "debug", skip(self), ret)]
37593774
pub fn ast_const_to_const(
37603775
&self,
37613776
ast_ct: &hir::ConstArg<'_>,
3762-
param_def_id: DefId,
3777+
arg_param: impl Into<ConstArgsParam>,
3778+
) -> Const<'tcx> {
3779+
self.ast_const_to_const_inner(ast_ct, arg_param.into())
3780+
}
3781+
3782+
#[instrument(level = "debug", skip(self), ret)]
3783+
fn ast_const_to_const_inner(
3784+
&self,
3785+
ast_ct: &hir::ConstArg<'_>,
3786+
arg_param: ConstArgsParam,
37633787
) -> Const<'tcx> {
37643788
let tcx = self.tcx();
37653789

37663790
match ast_ct.kind {
3791+
hir::ConstArgKind::Infer(_, _) => {
3792+
self.ct_infer(arg_param.to_ty(tcx).subst_identity(), None, ast_ct.span())
3793+
}
37673794
hir::ConstArgKind::AnonConst(_, ct) => {
3768-
tcx.feed_anon_const_type(ct.def_id, tcx.type_of(param_def_id));
3795+
tcx.feed_anon_const_type(ct.def_id, arg_param.to_ty(tcx));
37693796
Const::from_anon_const(tcx, ct.def_id)
37703797
}
37713798
hir::ConstArgKind::Param(_, path) => match path {

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector {
128128
}
129129
intravisit::walk_ty(self, t)
130130
}
131+
fn visit_const_arg(&mut self, c: &'v hir::ConstArg<'v>) {
132+
if let hir::ConstArgKind::Infer(_, span) = c.kind {
133+
self.0.push(span)
134+
}
135+
intravisit::walk_const_arg(self, c)
136+
}
131137
fn visit_generic_arg(&mut self, generic_arg: &'v hir::GenericArg<'v>) {
132138
match generic_arg {
133139
hir::GenericArg::Infer(inf) => {
@@ -138,12 +144,6 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector {
138144
_ => {}
139145
}
140146
}
141-
fn visit_array_length(&mut self, length: &'v hir::ArrayLen) {
142-
if let &hir::ArrayLen::Infer(_, span) = length {
143-
self.0.push(span);
144-
}
145-
intravisit::walk_array_len(self, length)
146-
}
147147
}
148148

149149
struct CollectItemTypesVisitor<'tcx> {
@@ -1017,7 +1017,7 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
10171017
Infer => true,
10181018
Slice(ty) => is_suggestable_infer_ty(ty),
10191019
Array(ty, length) => {
1020-
is_suggestable_infer_ty(ty) || matches!(length, hir::ArrayLen::Infer(_, _))
1020+
is_suggestable_infer_ty(ty) || matches!(length.kind, hir::ConstArgKind::Infer(_, _))
10211021
}
10221022
Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
10231023
Ptr(mut_ty) | Ref(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ impl<'a> State<'a> {
350350
self.word("[");
351351
self.print_type(ty);
352352
self.word("; ");
353-
self.print_array_length(length);
353+
self.print_const_arg(length);
354354
self.word("]");
355355
}
356356
hir::TyKind::Typeof(ref e) => {
@@ -376,6 +376,7 @@ impl<'a> State<'a> {
376376
match &const_arg.kind {
377377
hir::ConstArgKind::AnonConst(_, ct) => self.print_anon_const(ct),
378378
hir::ConstArgKind::Param(_, path) => self.print_qpath(path, false),
379+
hir::ConstArgKind::Infer(_, _) => self.word("_"),
379380
}
380381
self.end();
381382
}
@@ -1028,13 +1029,6 @@ impl<'a> State<'a> {
10281029
self.print_else(elseopt)
10291030
}
10301031

1031-
pub fn print_array_length(&mut self, len: &hir::ArrayLen) {
1032-
match len {
1033-
hir::ArrayLen::Infer(_, _) => self.word("_"),
1034-
hir::ArrayLen::Body(ct) => self.print_anon_const(ct),
1035-
}
1036-
}
1037-
10381032
pub fn print_anon_const(&mut self, constant: &hir::AnonConst) {
10391033
self.ann.nested(self, Nested::Body(constant.body))
10401034
}
@@ -1112,12 +1106,12 @@ impl<'a> State<'a> {
11121106
self.end()
11131107
}
11141108

1115-
fn print_expr_repeat(&mut self, element: &hir::Expr<'_>, count: &hir::ArrayLen) {
1109+
fn print_expr_repeat(&mut self, element: &hir::Expr<'_>, count: &hir::ConstArg<'_>) {
11161110
self.ibox(INDENT_UNIT);
11171111
self.word("[");
11181112
self.print_expr(element);
11191113
self.word_space(";");
1120-
self.print_array_length(count);
1114+
self.print_const_arg(count);
11211115
self.word("]");
11221116
self.end()
11231117
}

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use rustc_hir::intravisit::Visitor;
3333
use rustc_hir::lang_items::LangItem;
3434
use rustc_hir::{ExprKind, HirId, QPath};
3535
use rustc_hir_analysis::astconv::AstConv as _;
36+
use rustc_hir_analysis::astconv::ConstArgsParam;
3637
use rustc_hir_analysis::check::ty_kind_suggestion;
3738
use rustc_infer::infer;
3839
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -1347,7 +1348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13471348
return
13481349
};
13491350
if let hir::TyKind::Array(_, length) = ty.peel_refs().kind
1350-
&& let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length
1351+
&& let hir::ConstArgKind::AnonConst(_, hir::AnonConst { hir_id, .. }) = length.kind
13511352
&& let Some(span) = self.tcx.hir().opt_span(hir_id)
13521353
{
13531354
match self.tcx.sess.diagnostic().steal_diagnostic(span, StashKey::UnderscoreForArrayLengths) {
@@ -1387,12 +1388,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13871388
fn check_expr_repeat(
13881389
&self,
13891390
element: &'tcx hir::Expr<'tcx>,
1390-
count: &'tcx hir::ArrayLen,
1391+
count: &'tcx hir::ConstArg<'_>,
13911392
expected: Expectation<'tcx>,
13921393
expr: &'tcx hir::Expr<'tcx>,
13931394
) -> Ty<'tcx> {
13941395
let tcx = self.tcx;
1395-
let count = self.array_length_to_const(count);
1396+
let count = self.const_arg_to_const(count, ConstArgsParam::ArrayLen);
13961397
if let Some(count) = count.try_eval_target_usize(tcx, self.param_env) {
13971398
self.suggest_array_len(expr, count);
13981399
}

0 commit comments

Comments
 (0)