mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-22 20:03:37 +00:00
Rollup merge of #133589 - voidc:remove-array-len, r=boxyuwu
Remove `hir::ArrayLen` This refactoring removes `hir::ArrayLen`, replacing it with `hir::ConstArg`. To represent inferred array lengths (previously `hir::ArrayLen::Infer`), a new variant `ConstArgKind::Infer` is added. r? `@BoxyUwU`
This commit is contained in:
commit
811eaebf7e
@ -116,7 +116,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)),
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -1257,9 +1257,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;
|
||||
@ -2007,14 +2008,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,
|
||||
@ -2023,10 +2022,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),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -151,11 +151,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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -145,7 +145,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;
|
||||
}
|
||||
@ -579,8 +579,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);
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -2090,6 +2090,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),
|
||||
}
|
||||
}
|
||||
|
||||
@ -2310,13 +2311,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(),
|
||||
|
@ -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("_"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1073,12 +1066,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()
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -487,24 +487,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),
|
||||
@ -1279,7 +1267,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()
|
||||
|
@ -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()
|
||||
|
@ -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"),
|
||||
|
@ -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(),
|
||||
|
@ -290,6 +290,7 @@ pub(crate) fn clean_const<'tcx>(
|
||||
ConstantKind::Path { path: qpath_to_string(qpath).into() }
|
||||
}
|
||||
hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body },
|
||||
hir::ConstArgKind::Infer(..) => ConstantKind::Infer,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1803,30 +1804,27 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
|
||||
}
|
||||
TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))),
|
||||
TyKind::Pat(ty, pat) => Type::Pat(Box::new(clean_ty(ty, cx)), format!("{pat:?}").into()),
|
||||
TyKind::Array(ty, ref length) => {
|
||||
let length = match length {
|
||||
hir::ArrayLen::Infer(..) => "_".to_string(),
|
||||
hir::ArrayLen::Body(const_arg) => {
|
||||
// NOTE(min_const_generics): We can't use `const_eval_poly` for constants
|
||||
// as we currently do not supply the parent generics to anonymous constants
|
||||
// but do allow `ConstKind::Param`.
|
||||
//
|
||||
// `const_eval_poly` tries to first substitute generic parameters which
|
||||
// results in an ICE while manually constructing the constant and using `eval`
|
||||
// does nothing for `ConstKind::Param`.
|
||||
TyKind::Array(ty, ref const_arg) => {
|
||||
// NOTE(min_const_generics): We can't use `const_eval_poly` for constants
|
||||
// as we currently do not supply the parent generics to anonymous constants
|
||||
// but do allow `ConstKind::Param`.
|
||||
//
|
||||
// `const_eval_poly` tries to first substitute generic parameters which
|
||||
// results in an ICE while manually constructing the constant and using `eval`
|
||||
// does nothing for `ConstKind::Param`.
|
||||
let length = match const_arg.kind {
|
||||
hir::ConstArgKind::Infer(..) => "_".to_string(),
|
||||
hir::ConstArgKind::Anon(hir::AnonConst { def_id, .. }) => {
|
||||
let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No);
|
||||
let typing_env = ty::TypingEnv::post_analysis(cx.tcx, *def_id);
|
||||
let ct = cx.tcx.normalize_erasing_regions(typing_env, ct);
|
||||
print_const(cx, ct)
|
||||
}
|
||||
hir::ConstArgKind::Path(..) => {
|
||||
let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No);
|
||||
let ct = if let hir::ConstArgKind::Anon(hir::AnonConst { def_id, .. }) =
|
||||
const_arg.kind
|
||||
{
|
||||
let typing_env = ty::TypingEnv::post_analysis(cx.tcx, *def_id);
|
||||
cx.tcx.normalize_erasing_regions(typing_env, ct)
|
||||
} else {
|
||||
ct
|
||||
};
|
||||
print_const(cx, ct)
|
||||
}
|
||||
};
|
||||
|
||||
Array(Box::new(clean_ty(ty, cx)), length.into())
|
||||
}
|
||||
TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()),
|
||||
|
@ -2399,6 +2399,8 @@ pub(crate) enum ConstantKind {
|
||||
Extern { def_id: DefId },
|
||||
/// `const FOO: u32 = ...;`
|
||||
Local { def_id: DefId, body: BodyId },
|
||||
/// An inferred constant as in `[10u8; _]`.
|
||||
Infer,
|
||||
}
|
||||
|
||||
impl Constant {
|
||||
@ -2424,6 +2426,7 @@ impl ConstantKind {
|
||||
ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => {
|
||||
rendered_const(tcx, tcx.hir().body(body), tcx.hir().body_owner_def_id(body))
|
||||
}
|
||||
ConstantKind::Infer { .. } => "_".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -2431,7 +2434,8 @@ impl ConstantKind {
|
||||
match *self {
|
||||
ConstantKind::TyConst { .. }
|
||||
| ConstantKind::Path { .. }
|
||||
| ConstantKind::Anonymous { .. } => None,
|
||||
| ConstantKind::Anonymous { .. }
|
||||
| ConstantKind::Infer => None,
|
||||
ConstantKind::Extern { def_id } | ConstantKind::Local { def_id, .. } => {
|
||||
print_evaluated_const(tcx, def_id, true, true)
|
||||
}
|
||||
@ -2442,7 +2446,8 @@ impl ConstantKind {
|
||||
match *self {
|
||||
ConstantKind::TyConst { .. }
|
||||
| ConstantKind::Extern { .. }
|
||||
| ConstantKind::Path { .. } => false,
|
||||
| ConstantKind::Path { .. }
|
||||
| ConstantKind::Infer => false,
|
||||
ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => {
|
||||
is_literal_expr(tcx, body.hir_id)
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::is_from_proc_macro;
|
||||
use clippy_utils::macros::macro_backtrace;
|
||||
use clippy_utils::source::snippet;
|
||||
use rustc_hir::{ArrayLen, Expr, ExprKind, Item, ItemKind, Node};
|
||||
use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::{self, ConstKind};
|
||||
@ -118,13 +118,13 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays {
|
||||
|
||||
/// Only giving help messages if the expr does not contains macro expanded codes.
|
||||
fn might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool {
|
||||
/// Check if the span of `ArrayLen` of a repeat expression is within the expr's span,
|
||||
/// Check if the span of `ConstArg` of a repeat expression is within the expr's span,
|
||||
/// if not, meaning this repeat expr is definitely from some proc-macro.
|
||||
///
|
||||
/// This is a fail-safe to a case where even the `is_from_proc_macro` is unable to determain the
|
||||
/// correct result.
|
||||
fn repeat_expr_might_be_expanded(expr: &Expr<'_>) -> bool {
|
||||
let ExprKind::Repeat(_, ArrayLen::Body(len_ct)) = expr.kind else {
|
||||
let ExprKind::Repeat(_, len_ct) = expr.kind else {
|
||||
return false;
|
||||
};
|
||||
!expr.span.contains(len_ct.span())
|
||||
|
@ -3,7 +3,7 @@ use rustc_ast::LitIntType;
|
||||
use rustc_ast::ast::{LitFloatType, LitKind};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir::{
|
||||
self as hir, ArrayLen, BindingMode, CaptureBy, Closure, ClosureKind, ConstArg, ConstArgKind, CoroutineKind,
|
||||
self as hir, BindingMode, CaptureBy, Closure, ClosureKind, ConstArg, ConstArgKind, CoroutineKind,
|
||||
ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
@ -278,6 +278,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
||||
chain!(self, "let ConstArgKind::Anon({anon_const}) = {const_arg}.kind");
|
||||
self.body(field!(anon_const.body));
|
||||
},
|
||||
ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -611,14 +612,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
||||
bind!(self, value, length);
|
||||
kind!("Repeat({value}, {length})");
|
||||
self.expr(value);
|
||||
match length.value {
|
||||
ArrayLen::Infer(..) => chain!(self, "let ArrayLen::Infer(..) = length"),
|
||||
ArrayLen::Body(const_arg) => {
|
||||
bind!(self, const_arg);
|
||||
chain!(self, "let ArrayLen::Body({const_arg}) = {length}");
|
||||
self.const_arg(const_arg);
|
||||
},
|
||||
}
|
||||
self.const_arg(length);
|
||||
},
|
||||
ExprKind::Err(_) => kind!("Err(_)"),
|
||||
ExprKind::DropTemps(expr) => {
|
||||
|
@ -5,7 +5,7 @@ use clippy_utils::visitors::for_each_expr_without_closures;
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_data_structures::packed::Pu128;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{ArrayLen, ConstArgKind, ExprKind, Node};
|
||||
use rustc_hir::{ConstArgKind, ExprKind, Node};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_session::declare_lint_pass;
|
||||
@ -60,8 +60,7 @@ impl LateLintPass<'_> for ZeroRepeatSideEffects {
|
||||
// doesn't seem as confusing as `[f(); 0]`. It would also have false positives when eg.
|
||||
// the const item depends on `#[cfg]s` and has different values in different compilation
|
||||
// sessions).
|
||||
else if let ExprKind::Repeat(inner_expr, length) = expr.kind
|
||||
&& let ArrayLen::Body(const_arg) = length
|
||||
else if let ExprKind::Repeat(inner_expr, const_arg) = expr.kind
|
||||
&& let ConstArgKind::Anon(anon_const) = const_arg.kind
|
||||
&& let length_expr = hir_map.body(anon_const.body).value
|
||||
&& !length_expr.span.from_expansion()
|
||||
|
@ -7,7 +7,7 @@ use rustc_data_structures::fx::FxHasher;
|
||||
use rustc_hir::MatchSource::TryDesugar;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{
|
||||
ArrayLen, AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr,
|
||||
AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr,
|
||||
ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime,
|
||||
LifetimeName, Pat, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitBoundModifiers, Ty,
|
||||
TyKind,
|
||||
@ -266,14 +266,6 @@ impl HirEqInterExpr<'_, '_, '_> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn eq_array_length(&mut self, left: ArrayLen<'_>, right: ArrayLen<'_>) -> bool {
|
||||
match (left, right) {
|
||||
(ArrayLen::Infer(..), ArrayLen::Infer(..)) => true,
|
||||
(ArrayLen::Body(l_ct), ArrayLen::Body(r_ct)) => self.eq_const_arg(l_ct, r_ct),
|
||||
(_, _) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eq_body(&mut self, left: BodyId, right: BodyId) -> bool {
|
||||
// swap out TypeckResults when hashing a body
|
||||
let old_maybe_typeck_results = self.inner.maybe_typeck_results.replace((
|
||||
@ -383,7 +375,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
||||
},
|
||||
(ExprKind::Path(l), ExprKind::Path(r)) => self.eq_qpath(l, r),
|
||||
(&ExprKind::Repeat(le, ll), &ExprKind::Repeat(re, rl)) => {
|
||||
self.eq_expr(le, re) && self.eq_array_length(ll, rl)
|
||||
self.eq_expr(le, re) && self.eq_const_arg(ll, rl)
|
||||
},
|
||||
(ExprKind::Ret(l), ExprKind::Ret(r)) => both(l.as_ref(), r.as_ref(), |l, r| self.eq_expr(l, r)),
|
||||
(&ExprKind::Struct(l_path, lf, ref lo), &ExprKind::Struct(r_path, rf, ref ro)) => {
|
||||
@ -469,8 +461,10 @@ impl HirEqInterExpr<'_, '_, '_> {
|
||||
match (&left.kind, &right.kind) {
|
||||
(ConstArgKind::Path(l_p), ConstArgKind::Path(r_p)) => self.eq_qpath(l_p, r_p),
|
||||
(ConstArgKind::Anon(l_an), ConstArgKind::Anon(r_an)) => self.eq_body(l_an.body, r_an.body),
|
||||
(ConstArgKind::Infer(..), ConstArgKind::Infer(..)) => true,
|
||||
// Use explicit match for now since ConstArg is undergoing flux.
|
||||
(ConstArgKind::Path(..), ConstArgKind::Anon(..)) | (ConstArgKind::Anon(..), ConstArgKind::Path(..)) => {
|
||||
(ConstArgKind::Path(..), ConstArgKind::Anon(..)) | (ConstArgKind::Anon(..), ConstArgKind::Path(..))
|
||||
| (ConstArgKind::Infer(..), _) | (_, ConstArgKind::Infer(..)) => {
|
||||
false
|
||||
},
|
||||
}
|
||||
@ -589,7 +583,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
||||
pub fn eq_ty(&mut self, left: &Ty<'_>, right: &Ty<'_>) -> bool {
|
||||
match (&left.kind, &right.kind) {
|
||||
(&TyKind::Slice(l_vec), &TyKind::Slice(r_vec)) => self.eq_ty(l_vec, r_vec),
|
||||
(&TyKind::Array(lt, ll), &TyKind::Array(rt, rl)) => self.eq_ty(lt, rt) && self.eq_array_length(ll, rl),
|
||||
(&TyKind::Array(lt, ll), &TyKind::Array(rt, rl)) => self.eq_ty(lt, rt) && self.eq_const_arg(ll, rl),
|
||||
(TyKind::Ptr(l_mut), TyKind::Ptr(r_mut)) => l_mut.mutbl == r_mut.mutbl && self.eq_ty(l_mut.ty, r_mut.ty),
|
||||
(TyKind::Ref(_, l_rmut), TyKind::Ref(_, r_rmut)) => {
|
||||
l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(l_rmut.ty, r_rmut.ty)
|
||||
@ -1008,7 +1002,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||
},
|
||||
ExprKind::Repeat(e, len) => {
|
||||
self.hash_expr(e);
|
||||
self.hash_array_length(len);
|
||||
self.hash_const_arg(len);
|
||||
},
|
||||
ExprKind::Ret(ref e) => {
|
||||
if let Some(e) = *e {
|
||||
@ -1201,7 +1195,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||
},
|
||||
&TyKind::Array(ty, len) => {
|
||||
self.hash_ty(ty);
|
||||
self.hash_array_length(len);
|
||||
self.hash_const_arg(len);
|
||||
},
|
||||
TyKind::Pat(ty, pat) => {
|
||||
self.hash_ty(ty);
|
||||
@ -1252,13 +1246,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hash_array_length(&mut self, length: ArrayLen<'_>) {
|
||||
match length {
|
||||
ArrayLen::Infer(..) => {},
|
||||
ArrayLen::Body(ct) => self.hash_const_arg(ct),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hash_body(&mut self, body_id: BodyId) {
|
||||
// swap out TypeckResults when hashing a body
|
||||
let old_maybe_typeck_results = self.maybe_typeck_results.replace(self.cx.tcx.typeck_body(body_id));
|
||||
@ -1270,6 +1257,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||
match &const_arg.kind {
|
||||
ConstArgKind::Path(path) => self.hash_qpath(path),
|
||||
ConstArgKind::Anon(anon) => self.hash_body(anon.body),
|
||||
ConstArgKind::Infer(..) => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ use rustc_hir::definitions::{DefPath, DefPathData};
|
||||
use rustc_hir::hir_id::{HirIdMap, HirIdSet};
|
||||
use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
|
||||
use rustc_hir::{
|
||||
self as hir, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind, ConstContext,
|
||||
self as hir, Arm, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind, ConstContext,
|
||||
Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind,
|
||||
ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode, Param, Pat,
|
||||
PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef,
|
||||
@ -910,7 +910,7 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
||||
_ => false,
|
||||
},
|
||||
ExprKind::Tup(items) | ExprKind::Array(items) => items.iter().all(|x| is_default_equivalent(cx, x)),
|
||||
ExprKind::Repeat(x, ArrayLen::Body(len)) => {
|
||||
ExprKind::Repeat(x, len) => {
|
||||
if let ConstArgKind::Anon(anon_const) = len.kind
|
||||
&& let ExprKind::Lit(const_lit) = cx.tcx.hir().body(anon_const.body).value.kind
|
||||
&& let LitKind::Int(v, _) = const_lit.node
|
||||
@ -940,7 +940,7 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: &
|
||||
..
|
||||
}) => return sym.is_empty() && is_path_lang_item(cx, ty, LangItem::String),
|
||||
ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec),
|
||||
ExprKind::Repeat(_, ArrayLen::Body(len)) => {
|
||||
ExprKind::Repeat(_, len) => {
|
||||
if let ConstArgKind::Anon(anon_const) = len.kind
|
||||
&& let ExprKind::Lit(const_lit) = cx.tcx.hir().body(anon_const.body).value.kind
|
||||
&& let LitKind::Int(v, _) = const_lit.node
|
||||
|
@ -1,8 +1,7 @@
|
||||
if let ExprKind::Repeat(value, length) = expr.kind
|
||||
&& let ExprKind::Lit(ref lit) = value.kind
|
||||
&& let LitKind::Int(1, LitIntType::Unsigned(UintTy::U8)) = lit.node
|
||||
&& let ArrayLen::Body(const_arg) = length
|
||||
&& let ConstArgKind::Anon(anon_const) = const_arg.kind
|
||||
&& let ConstArgKind::Anon(anon_const) = length.kind
|
||||
&& expr1 = &cx.tcx.hir().body(anon_const.body).value
|
||||
&& let ExprKind::Lit(ref lit1) = expr1.kind
|
||||
&& let LitKind::Int(5, LitIntType::Unsuffixed) = lit1.node
|
||||
|
Loading…
Reference in New Issue
Block a user