Skip to content

Commit

Permalink
Rollup merge of rust-lang#101492 - TaKO8Ki:suggest-adding-array-lengt…
Browse files Browse the repository at this point in the history
…h-to-ref-to-array, r=oli-obk

Suggest adding array lengths to references to arrays if possible

ref: rust-lang#100590 (review)
  • Loading branch information
Dylan-DPC authored Sep 9, 2022
2 parents d9609c7 + 1e38442 commit bef48f9
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 29 deletions.
8 changes: 8 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2401,6 +2401,14 @@ impl<'hir> Ty<'hir> {
_ => None,
}
}

pub fn peel_refs(&self) -> &Self {
let mut final_ty = self;
while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind {
final_ty = &ty;
}
final_ty
}
}

/// Not represented directly in the AST; referred to by name through a `ty_path`.
Expand Down
47 changes: 23 additions & 24 deletions compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1305,31 +1305,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

fn suggest_array_len(&self, expr: &'tcx hir::Expr<'tcx>, array_len: u64) {
if let Some(parent_hir_id) = self.tcx.hir().find_parent_node(expr.hir_id) {
let ty = match self.tcx.hir().find(parent_hir_id) {
Some(
hir::Node::Local(hir::Local { ty: Some(ty), .. })
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _), .. }),
) => Some(ty),
_ => None,
};
if let Some(ty) = ty
&& let hir::TyKind::Array(_, length) = ty.kind
&& let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length
&& let Some(span) = self.tcx.hir().opt_span(hir_id)
{
match self.tcx.sess.diagnostic().steal_diagnostic(span, StashKey::UnderscoreForArrayLengths) {
Some(mut err) => {
err.span_suggestion(
span,
"consider specifying the array length",
array_len,
Applicability::MaybeIncorrect,
);
err.emit();
}
None => ()
let parent_node = self.tcx.hir().parent_iter(expr.hir_id).find(|(_, node)| {
!matches!(node, hir::Node::Expr(hir::Expr { kind: hir::ExprKind::AddrOf(..), .. }))
});
let Some((_,
hir::Node::Local(hir::Local { ty: Some(ty), .. })
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _), .. }))
) = parent_node else {
return
};
if let hir::TyKind::Array(_, length) = ty.peel_refs().kind
&& let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length
&& let Some(span) = self.tcx.hir().opt_span(hir_id)
{
match self.tcx.sess.diagnostic().steal_diagnostic(span, StashKey::UnderscoreForArrayLengths) {
Some(mut err) => {
err.span_suggestion(
span,
"consider specifying the array length",
array_len,
Applicability::MaybeIncorrect,
);
err.emit();
}
None => ()
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/array-slice-vec/suggest-array-length.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,22 @@ fn main() {
const Foo: [i32; 3] = [1, 2, 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
const REF_FOO: &[u8; 1] = &[1];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
let foo: [i32; 3] = [1, 2, 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
let bar: [i32; 3] = [0; 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
let ref_foo: &[i32; 3] = &[1, 2, 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
let ref_bar: &[i32; 3] = &[0; 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
let multiple_ref_foo: &&[i32; 3] = &&[1, 2, 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
}
12 changes: 12 additions & 0 deletions src/test/ui/array-slice-vec/suggest-array-length.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,22 @@ fn main() {
const Foo: [i32; _] = [1, 2, 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
const REF_FOO: &[u8; _] = &[1];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
let foo: [i32; _] = [1, 2, 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
let bar: [i32; _] = [0; 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
let ref_foo: &[i32; _] = &[1, 2, 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
let ref_bar: &[i32; _] = &[0; 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
let multiple_ref_foo: &&[i32; _] = &&[1, 2, 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
}
70 changes: 65 additions & 5 deletions src/test/ui/array-slice-vec/suggest-array-length.stderr
Original file line number Diff line number Diff line change
@@ -1,21 +1,45 @@
error: in expressions, `_` can only be used on the left-hand side of an assignment
--> $DIR/suggest-array-length.rs:8:20
--> $DIR/suggest-array-length.rs:11:20
|
LL | let foo: [i32; _] = [1, 2, 3];
| ^ `_` not allowed here

error: in expressions, `_` can only be used on the left-hand side of an assignment
--> $DIR/suggest-array-length.rs:11:20
--> $DIR/suggest-array-length.rs:14:20
|
LL | let bar: [i32; _] = [0; 3];
| ^ `_` not allowed here

error: in expressions, `_` can only be used on the left-hand side of an assignment
--> $DIR/suggest-array-length.rs:17:25
|
LL | let ref_foo: &[i32; _] = &[1, 2, 3];
| ^ `_` not allowed here

error: in expressions, `_` can only be used on the left-hand side of an assignment
--> $DIR/suggest-array-length.rs:20:25
|
LL | let ref_bar: &[i32; _] = &[0; 3];
| ^ `_` not allowed here

error: in expressions, `_` can only be used on the left-hand side of an assignment
--> $DIR/suggest-array-length.rs:23:35
|
LL | let multiple_ref_foo: &&[i32; _] = &&[1, 2, 3];
| ^ `_` not allowed here

error: in expressions, `_` can only be used on the left-hand side of an assignment
--> $DIR/suggest-array-length.rs:5:22
|
LL | const Foo: [i32; _] = [1, 2, 3];
| ^ `_` not allowed here

error: in expressions, `_` can only be used on the left-hand side of an assignment
--> $DIR/suggest-array-length.rs:8:26
|
LL | const REF_FOO: &[u8; _] = &[1];
| ^ `_` not allowed here

error[E0658]: using `_` for array lengths is unstable
--> $DIR/suggest-array-length.rs:5:22
|
Expand All @@ -26,7 +50,16 @@ LL | const Foo: [i32; _] = [1, 2, 3];
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable

error[E0658]: using `_` for array lengths is unstable
--> $DIR/suggest-array-length.rs:8:20
--> $DIR/suggest-array-length.rs:8:26
|
LL | const REF_FOO: &[u8; _] = &[1];
| ^ help: consider specifying the array length: `1`
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable

error[E0658]: using `_` for array lengths is unstable
--> $DIR/suggest-array-length.rs:11:20
|
LL | let foo: [i32; _] = [1, 2, 3];
| ^ help: consider specifying the array length: `3`
Expand All @@ -35,14 +68,41 @@ LL | let foo: [i32; _] = [1, 2, 3];
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable

error[E0658]: using `_` for array lengths is unstable
--> $DIR/suggest-array-length.rs:11:20
--> $DIR/suggest-array-length.rs:14:20
|
LL | let bar: [i32; _] = [0; 3];
| ^ help: consider specifying the array length: `3`
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable

error: aborting due to 6 previous errors
error[E0658]: using `_` for array lengths is unstable
--> $DIR/suggest-array-length.rs:17:25
|
LL | let ref_foo: &[i32; _] = &[1, 2, 3];
| ^ help: consider specifying the array length: `3`
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable

error[E0658]: using `_` for array lengths is unstable
--> $DIR/suggest-array-length.rs:20:25
|
LL | let ref_bar: &[i32; _] = &[0; 3];
| ^ help: consider specifying the array length: `3`
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable

error[E0658]: using `_` for array lengths is unstable
--> $DIR/suggest-array-length.rs:23:35
|
LL | let multiple_ref_foo: &&[i32; _] = &&[1, 2, 3];
| ^ help: consider specifying the array length: `3`
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable

error: aborting due to 14 previous errors

For more information about this error, try `rustc --explain E0658`.

0 comments on commit bef48f9

Please sign in to comment.