Rollup merge of #91907 - lcnr:const-arg-infer, r=BoxyUwU
Allow `_` as the length of array types and repeat expressions r? `@BoxyUwU` cc `@varkor`
This commit is contained in:
commit
d7a60337fc
@ -59,6 +59,7 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx
|
||||
if let ItemKind::Struct(data, _) = &item.kind;
|
||||
if let Some(last_field) = data.fields().last();
|
||||
if let rustc_hir::TyKind::Array(_, length) = last_field.ty.kind;
|
||||
if let rustc_hir::ArrayLen::Body(length) = length;
|
||||
|
||||
// Then check if that that array zero-sized
|
||||
let length_ldid = cx.tcx.hir().local_def_id(length.hir_id);
|
||||
|
@ -6,7 +6,7 @@
|
||||
use rustc_ast::LitIntType;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::{ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind};
|
||||
use rustc_hir::{ArrayLen, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::symbol::{Ident, Symbol};
|
||||
@ -567,7 +567,14 @@ macro_rules! kind {
|
||||
bind!(self, value, length);
|
||||
kind!("Repeat({value}, {length})");
|
||||
self.expr(value);
|
||||
self.body(field!(length.body));
|
||||
match length.value {
|
||||
ArrayLen::Infer(..) => out!("if let ArrayLen::Infer(..) = length;"),
|
||||
ArrayLen::Body(anon_const) => {
|
||||
bind!(self, anon_const);
|
||||
out!("if let ArrayLen::Body({anon_const}) = {length};");
|
||||
self.body(field!(anon_const.body));
|
||||
}
|
||||
}
|
||||
},
|
||||
ExprKind::Err => kind!("Err"),
|
||||
ExprKind::DropTemps(expr) => {
|
||||
|
@ -334,12 +334,17 @@ fn print_expr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, indent: usize) {
|
||||
println!("{}anon_const:", ind);
|
||||
print_expr(cx, &cx.tcx.hir().body(anon_const.body).value, indent + 1);
|
||||
},
|
||||
hir::ExprKind::Repeat(val, ref anon_const) => {
|
||||
hir::ExprKind::Repeat(val, length) => {
|
||||
println!("{}Repeat", ind);
|
||||
println!("{}value:", ind);
|
||||
print_expr(cx, val, indent + 1);
|
||||
println!("{}repeat count:", ind);
|
||||
print_expr(cx, &cx.tcx.hir().body(anon_const.body).value, indent + 1);
|
||||
match length {
|
||||
hir::ArrayLen::Infer(_, _) => println!("{}repeat count: _", ind),
|
||||
hir::ArrayLen::Body(anon_const) => {
|
||||
print_expr(cx, &cx.tcx.hir().body(anon_const.body).value, indent + 1)
|
||||
}
|
||||
}
|
||||
},
|
||||
hir::ExprKind::Err => {
|
||||
println!("{}Err", ind);
|
||||
|
@ -8,7 +8,7 @@
|
||||
use rustc_hir::{
|
||||
BinOpKind, Block, BodyId, Expr, ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, Guard, HirId,
|
||||
InlineAsmOperand, Let, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path, PathSegment, QPath, Stmt,
|
||||
StmtKind, Ty, TyKind, TypeBinding,
|
||||
StmtKind, Ty, TyKind, TypeBinding, ArrayLen
|
||||
};
|
||||
use rustc_lexer::{tokenize, TokenKind};
|
||||
use rustc_lint::LateContext;
|
||||
@ -170,6 +170,14 @@ fn eq_block(&mut self, left: &Block<'_>, right: &Block<'_>) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
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_body(l_ct.body, r_ct.body),
|
||||
(_, _) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eq_body(&mut self, left: BodyId, right: BodyId) -> bool {
|
||||
let cx = self.inner.cx;
|
||||
let eval_const = |body| constant_context(cx, cx.tcx.typeck_body(body)).expr(&cx.tcx.hir().body(body).value);
|
||||
@ -194,8 +202,8 @@ pub fn eq_expr(&mut self, left: &Expr<'_>, right: &Expr<'_>) -> bool {
|
||||
}
|
||||
|
||||
let is_eq = match (
|
||||
&reduce_exprkind(self.inner.cx, &left.kind),
|
||||
&reduce_exprkind(self.inner.cx, &right.kind),
|
||||
reduce_exprkind(self.inner.cx, &left.kind),
|
||||
reduce_exprkind(self.inner.cx, &right.kind),
|
||||
) {
|
||||
(&ExprKind::AddrOf(lb, l_mut, le), &ExprKind::AddrOf(rb, r_mut, re)) => {
|
||||
lb == rb && l_mut == r_mut && self.eq_expr(le, re)
|
||||
@ -232,7 +240,7 @@ pub fn eq_expr(&mut self, left: &Expr<'_>, right: &Expr<'_>) -> bool {
|
||||
},
|
||||
(&ExprKind::Index(la, li), &ExprKind::Index(ra, ri)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),
|
||||
(&ExprKind::If(lc, lt, ref le), &ExprKind::If(rc, rt, ref re)) => {
|
||||
self.eq_expr(lc, rc) && self.eq_expr(&**lt, &**rt) && both(le, re, |l, r| self.eq_expr(l, r))
|
||||
self.eq_expr(lc, rc) && self.eq_expr(lt, rt) && both(le, re, |l, r| self.eq_expr(l, r))
|
||||
},
|
||||
(&ExprKind::Let(l), &ExprKind::Let(r)) => {
|
||||
self.eq_pat(l.pat, r.pat) && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && self.eq_expr(l.init, r.init)
|
||||
@ -253,8 +261,8 @@ pub fn eq_expr(&mut self, left: &Expr<'_>, right: &Expr<'_>) -> bool {
|
||||
(&ExprKind::MethodCall(l_path, _, l_args, _), &ExprKind::MethodCall(r_path, _, r_args, _)) => {
|
||||
self.inner.allow_side_effects && self.eq_path_segment(l_path, r_path) && self.eq_exprs(l_args, r_args)
|
||||
},
|
||||
(&ExprKind::Repeat(le, ref ll_id), &ExprKind::Repeat(re, ref rl_id)) => {
|
||||
self.eq_expr(le, re) && self.eq_body(ll_id.body, rl_id.body)
|
||||
(&ExprKind::Repeat(le, ll), &ExprKind::Repeat(re, rl)) => {
|
||||
self.eq_expr(le, re) && self.eq_array_length(ll, rl)
|
||||
},
|
||||
(&ExprKind::Ret(ref l), &ExprKind::Ret(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)),
|
||||
(&ExprKind::Path(ref l), &ExprKind::Path(ref r)) => self.eq_qpath(l, r),
|
||||
@ -391,8 +399,8 @@ pub fn eq_path_segment(&mut self, left: &PathSegment<'_>, right: &PathSegment<'_
|
||||
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, ref ll_id), &TyKind::Array(rt, ref rl_id)) => {
|
||||
self.eq_ty(lt, rt) && self.eq_body(ll_id.body, rl_id.body)
|
||||
(&TyKind::Array(lt, ll), &TyKind::Array(rt, rl)) => {
|
||||
self.eq_ty(lt, rt) && self.eq_array_length(ll, rl)
|
||||
},
|
||||
(&TyKind::Ptr(ref l_mut), &TyKind::Ptr(ref r_mut)) => {
|
||||
l_mut.mutbl == r_mut.mutbl && self.eq_ty(&*l_mut.ty, &*r_mut.ty)
|
||||
@ -714,9 +722,9 @@ pub fn hash_expr(&mut self, e: &Expr<'_>) {
|
||||
ExprKind::ConstBlock(ref l_id) => {
|
||||
self.hash_body(l_id.body);
|
||||
},
|
||||
ExprKind::Repeat(e, ref l_id) => {
|
||||
ExprKind::Repeat(e, len) => {
|
||||
self.hash_expr(e);
|
||||
self.hash_body(l_id.body);
|
||||
self.hash_array_length(len);
|
||||
},
|
||||
ExprKind::Ret(ref e) => {
|
||||
if let Some(e) = *e {
|
||||
@ -906,9 +914,9 @@ pub fn hash_tykind(&mut self, ty: &TyKind<'_>) {
|
||||
TyKind::Slice(ty) => {
|
||||
self.hash_ty(ty);
|
||||
},
|
||||
TyKind::Array(ty, anon_const) => {
|
||||
&TyKind::Array(ty, len) => {
|
||||
self.hash_ty(ty);
|
||||
self.hash_body(anon_const.body);
|
||||
self.hash_array_length(len);
|
||||
},
|
||||
TyKind::Ptr(ref mut_ty) => {
|
||||
self.hash_ty(mut_ty.ty);
|
||||
@ -953,6 +961,13 @@ pub fn hash_tykind(&mut self, ty: &TyKind<'_>) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hash_array_length(&mut self, length: ArrayLen) {
|
||||
match length {
|
||||
ArrayLen::Infer(..) => {}
|
||||
ArrayLen::Body(anon_const) => self.hash_body(anon_const.body),
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
@ -79,7 +79,7 @@
|
||||
def, Arm, BindingAnnotation, Block, BlockCheckMode, Body, Constness, Destination, Expr, ExprKind, FnDecl,
|
||||
ForeignItem, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local,
|
||||
MatchSource, Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem,
|
||||
TraitItemKind, TraitRef, TyKind, UnOp,
|
||||
TraitItemKind, TraitRef, TyKind, UnOp, ArrayLen
|
||||
};
|
||||
use rustc_lint::{LateContext, Level, Lint, LintContext};
|
||||
use rustc_middle::hir::exports::Export;
|
||||
@ -703,8 +703,9 @@ 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, y) => if_chain! {
|
||||
if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(y.body).value.kind;
|
||||
ExprKind::Repeat(x, len) => if_chain! {
|
||||
if let ArrayLen::Body(len) = len;
|
||||
if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(len.body).value.kind;
|
||||
if let LitKind::Int(v, _) = const_lit.node;
|
||||
if v <= 32 && is_default_equivalent(cx, x);
|
||||
then {
|
||||
|
@ -2,7 +2,8 @@ if_chain! {
|
||||
if let ExprKind::Repeat(value, length) = expr.kind;
|
||||
if let ExprKind::Lit(ref lit) = value.kind;
|
||||
if let LitKind::Int(1, LitIntType::Unsigned(UintTy::U8)) = lit.node;
|
||||
let expr1 = &cx.tcx.hir().body(length.body).value;
|
||||
if let ArrayLen::Body(anon_const) = length;
|
||||
let expr1 = &cx.tcx.hir().body(anon_const.body).value;
|
||||
if let ExprKind::Lit(ref lit1) = expr1.kind;
|
||||
if let LitKind::Int(5, LitIntType::Unsuffixed) = lit1.node;
|
||||
then {
|
||||
|
Loading…
Reference in New Issue
Block a user