mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-24 05:33:27 +00:00
Auto merge of #8272 - flip1995:rustup, r=flip1995
Rustup r? `@ghost` changelog: none
This commit is contained in:
commit
97a5daa659
27 changed files with 139 additions and 93 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy"
|
||||
version = "0.1.59"
|
||||
version = "0.1.60"
|
||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
readme = "README.md"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy_lints"
|
||||
version = "0.1.59"
|
||||
version = "0.1.60"
|
||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
readme = "README.md"
|
||||
|
@ -13,7 +13,7 @@ cargo_metadata = "0.14"
|
|||
clippy_utils = { path = "../clippy_utils" }
|
||||
if_chain = "1.0"
|
||||
itertools = "0.10"
|
||||
pulldown-cmark = { version = "0.8", default-features = false }
|
||||
pulldown-cmark = { version = "0.9", default-features = false }
|
||||
quine-mc_cluskey = "0.2"
|
||||
regex-syntax = "0.6"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
|
|
@ -198,7 +198,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
|
|||
let ext_with_default = !variant
|
||||
.fields
|
||||
.iter()
|
||||
.all(|field| assigned_fields.iter().any(|(a, _)| a == &field.ident.name));
|
||||
.all(|field| assigned_fields.iter().any(|(a, _)| a == &field.name));
|
||||
|
||||
let field_list = assigned_fields
|
||||
.into_iter()
|
||||
|
|
|
@ -161,7 +161,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
|
|||
fields_def
|
||||
.iter()
|
||||
.find_map(|f_def| {
|
||||
if f_def.ident == field.ident
|
||||
if f_def.ident(self.cx.tcx) == field.ident
|
||||
{ Some(self.cx.tcx.type_of(f_def.did)) }
|
||||
else { None }
|
||||
});
|
||||
|
|
|
@ -543,16 +543,16 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
|
|||
},
|
||||
Start(Link(_, url, _)) => in_link = Some(url),
|
||||
End(Link(..)) => in_link = None,
|
||||
Start(Heading(_) | Paragraph | Item) => {
|
||||
if let Start(Heading(_)) = event {
|
||||
Start(Heading(_, _, _) | Paragraph | Item) => {
|
||||
if let Start(Heading(_, _, _)) = event {
|
||||
in_heading = true;
|
||||
}
|
||||
ticks_unbalanced = false;
|
||||
let (_, span) = get_current_span(spans, range.start);
|
||||
paragraph_span = first_line_of_span(cx, span);
|
||||
},
|
||||
End(Heading(_) | Paragraph | Item) => {
|
||||
if let End(Heading(_)) = event {
|
||||
End(Heading(_, _, _) | Paragraph | Item) => {
|
||||
if let End(Heading(_, _, _)) = event {
|
||||
in_heading = false;
|
||||
}
|
||||
if ticks_unbalanced {
|
||||
|
|
|
@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for InconsistentStructConstructor {
|
|||
then {
|
||||
let mut def_order_map = FxHashMap::default();
|
||||
for (idx, field) in variant.fields.iter().enumerate() {
|
||||
def_order_map.insert(field.ident.name, idx);
|
||||
def_order_map.insert(field.name, idx);
|
||||
}
|
||||
|
||||
if is_consistent_order(fields, &def_order_map) {
|
||||
|
|
|
@ -214,14 +214,14 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items
|
|||
{
|
||||
let mut current_and_super_traits = DefIdSet::default();
|
||||
fill_trait_set(visited_trait.def_id.to_def_id(), &mut current_and_super_traits, cx);
|
||||
let is_empty = sym!(is_empty);
|
||||
|
||||
let is_empty_method_found = current_and_super_traits
|
||||
.iter()
|
||||
.flat_map(|&i| cx.tcx.associated_items(i).in_definition_order())
|
||||
.flat_map(|&i| cx.tcx.associated_items(i).filter_by_name_unhygienic(is_empty))
|
||||
.any(|i| {
|
||||
i.kind == ty::AssocKind::Fn
|
||||
&& i.fn_has_self_parameter
|
||||
&& i.ident.name == sym!(is_empty)
|
||||
&& cx.tcx.fn_sig(i.def_id).inputs().skip_binder().len() == 1
|
||||
});
|
||||
|
||||
|
@ -458,7 +458,7 @@ fn is_empty_array(expr: &Expr<'_>) -> bool {
|
|||
fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
/// Gets an `AssocItem` and return true if it matches `is_empty(self)`.
|
||||
fn is_is_empty(cx: &LateContext<'_>, item: &ty::AssocItem) -> bool {
|
||||
if item.kind == ty::AssocKind::Fn && item.ident.name.as_str() == "is_empty" {
|
||||
if item.kind == ty::AssocKind::Fn {
|
||||
let sig = cx.tcx.fn_sig(item.def_id);
|
||||
let ty = sig.skip_binder();
|
||||
ty.inputs().len() == 1
|
||||
|
@ -469,10 +469,11 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||
|
||||
/// Checks the inherent impl's items for an `is_empty(self)` method.
|
||||
fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId) -> bool {
|
||||
let is_empty = sym!(is_empty);
|
||||
cx.tcx.inherent_impls(id).iter().any(|imp| {
|
||||
cx.tcx
|
||||
.associated_items(*imp)
|
||||
.in_definition_order()
|
||||
.filter_by_name_unhygienic(is_empty)
|
||||
.any(|item| is_is_empty(cx, item))
|
||||
})
|
||||
}
|
||||
|
@ -480,9 +481,10 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||
let ty = &cx.typeck_results().expr_ty(expr).peel_refs();
|
||||
match ty.kind() {
|
||||
ty::Dynamic(tt, ..) => tt.principal().map_or(false, |principal| {
|
||||
let is_empty = sym!(is_empty);
|
||||
cx.tcx
|
||||
.associated_items(principal.def_id())
|
||||
.in_definition_order()
|
||||
.filter_by_name_unhygienic(is_empty)
|
||||
.any(|item| is_is_empty(cx, item))
|
||||
}),
|
||||
ty::Projection(ref proj) => has_is_empty_impl(cx, proj.item_def_id),
|
||||
|
|
|
@ -8,7 +8,6 @@ use rustc_errors::Applicability;
|
|||
use rustc_hir as hir;
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::hygiene::ExpnKind;
|
||||
use rustc_span::{edition::Edition, sym, Span};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -97,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
|
|||
if let Res::Def(DefKind::Mod, id) = path.res;
|
||||
if !id.is_local();
|
||||
then {
|
||||
for kid in cx.tcx.item_children(id).iter() {
|
||||
for kid in cx.tcx.module_children(id).iter() {
|
||||
if let Res::Def(DefKind::Macro(_mac_type), mac_id) = kid.res {
|
||||
let span = mac_attr.span;
|
||||
let def_path = cx.tcx.def_path_str(mac_id);
|
||||
|
@ -105,34 +104,34 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if in_macro(item.span) {
|
||||
if item.span.from_expansion() {
|
||||
self.push_unique_macro_pat_ty(cx, item.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) {
|
||||
if in_macro(attr.span) {
|
||||
if attr.span.from_expansion() {
|
||||
self.push_unique_macro(cx, attr.span);
|
||||
}
|
||||
}
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
|
||||
if in_macro(expr.span) {
|
||||
if expr.span.from_expansion() {
|
||||
self.push_unique_macro(cx, expr.span);
|
||||
}
|
||||
}
|
||||
fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &hir::Stmt<'_>) {
|
||||
if in_macro(stmt.span) {
|
||||
if stmt.span.from_expansion() {
|
||||
self.push_unique_macro(cx, stmt.span);
|
||||
}
|
||||
}
|
||||
fn check_pat(&mut self, cx: &LateContext<'_>, pat: &hir::Pat<'_>) {
|
||||
if in_macro(pat.span) {
|
||||
if pat.span.from_expansion() {
|
||||
self.push_unique_macro_pat_ty(cx, pat.span);
|
||||
}
|
||||
}
|
||||
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &hir::Ty<'_>) {
|
||||
if in_macro(ty.span) {
|
||||
if ty.span.from_expansion() {
|
||||
self.push_unique_macro_pat_ty(cx, ty.span);
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +213,3 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn in_macro(span: Span) -> bool {
|
||||
span.from_expansion() && !matches!(span.ctxt().outer_expn_data().kind, ExpnKind::Desugaring(..))
|
||||
}
|
||||
|
|
|
@ -1138,7 +1138,7 @@ fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
|
|||
s.push_str("::");
|
||||
s
|
||||
},
|
||||
variant.ident.name,
|
||||
variant.name,
|
||||
match variant.ctor_kind {
|
||||
CtorKind::Fn if variant.fields.len() == 1 => "(_)",
|
||||
CtorKind::Fn => "(..)",
|
||||
|
|
|
@ -12,11 +12,10 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_hir::{
|
||||
BodyId, Expr, ExprKind, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind, UnOp,
|
||||
};
|
||||
use rustc_infer::traits::specialization_graph;
|
||||
use rustc_lint::{LateContext, LateLintPass, Lint};
|
||||
use rustc_middle::mir::interpret::{ConstValue, ErrorHandled};
|
||||
use rustc_middle::ty::adjustment::Adjust;
|
||||
use rustc_middle::ty::{self, AssocKind, Const, Ty};
|
||||
use rustc_middle::ty::{self, Const, Ty};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::{InnerSpan, Span, DUMMY_SP};
|
||||
use rustc_typeck::hir_ty_to_ty;
|
||||
|
@ -293,8 +292,10 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
|
|||
// Lint a trait impl item only when the definition is a generic type,
|
||||
// assuming an assoc const is not meant to be an interior mutable type.
|
||||
if let Some(of_trait_def_id) = of_trait_ref.trait_def_id();
|
||||
if let Some(of_assoc_item) = specialization_graph::Node::Trait(of_trait_def_id)
|
||||
.item(cx.tcx, impl_item.ident, AssocKind::Const, of_trait_def_id);
|
||||
if let Some(of_assoc_item) = cx
|
||||
.tcx
|
||||
.associated_item(impl_item.def_id)
|
||||
.trait_item_def_id;
|
||||
if cx
|
||||
.tcx
|
||||
.layout_of(cx.tcx.param_env(of_trait_def_id).and(
|
||||
|
@ -303,7 +304,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
|
|||
// and, in that case, the definition is *not* generic.
|
||||
cx.tcx.normalize_erasing_regions(
|
||||
cx.tcx.param_env(of_trait_def_id),
|
||||
cx.tcx.type_of(of_assoc_item.def_id),
|
||||
cx.tcx.type_of(of_assoc_item),
|
||||
),
|
||||
))
|
||||
.is_err();
|
||||
|
|
|
@ -58,7 +58,7 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'_>, item: &Item<'_
|
|||
// First check if last field is an array
|
||||
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::TyKind::Array(_, rustc_hir::ArrayLen::Body(length)) = last_field.ty.kind;
|
||||
|
||||
// Then check if that that array zero-sized
|
||||
let length_ldid = cx.tcx.hir().local_def_id(length.hir_id);
|
||||
|
|
|
@ -13,7 +13,6 @@ use rustc_hir::{
|
|||
};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::ty::AssocKind;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::Span;
|
||||
|
@ -143,10 +142,10 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
|
|||
// trait, not in the impl of the trait.
|
||||
let trait_method = cx
|
||||
.tcx
|
||||
.associated_items(impl_trait_ref.def_id)
|
||||
.find_by_name_and_kind(cx.tcx, impl_item.ident, AssocKind::Fn, impl_trait_ref.def_id)
|
||||
.associated_item(impl_item.def_id)
|
||||
.trait_item_def_id
|
||||
.expect("impl method matches a trait method");
|
||||
let trait_method_sig = cx.tcx.fn_sig(trait_method.def_id);
|
||||
let trait_method_sig = cx.tcx.fn_sig(trait_method);
|
||||
let trait_method_sig = cx.tcx.erase_late_bound_regions(trait_method_sig);
|
||||
|
||||
// `impl_inputs_outputs` is an iterator over the types (`hir::Ty`) declared in the
|
||||
|
|
|
@ -6,7 +6,7 @@ use rustc_ast::ast::{LitFloatType, LitKind};
|
|||
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 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
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);
|
||||
|
|
|
@ -929,9 +929,20 @@ pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
|
|||
let lang_item_path = cx.get_def_path(*item_def_id);
|
||||
if path_syms.starts_with(&lang_item_path) {
|
||||
if let [item] = &path_syms[lang_item_path.len()..] {
|
||||
for child in cx.tcx.item_children(*item_def_id) {
|
||||
if child.ident.name == *item {
|
||||
return true;
|
||||
if matches!(
|
||||
cx.tcx.def_kind(*item_def_id),
|
||||
DefKind::Mod | DefKind::Enum | DefKind::Trait
|
||||
) {
|
||||
for child in cx.tcx.module_children(*item_def_id) {
|
||||
if child.ident.name == *item {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for child in cx.tcx.associated_item_def_ids(*item_def_id) {
|
||||
if cx.tcx.item_name(*child) == *item {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -989,7 +1000,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
|
|||
|
||||
for &module in &[&paths::KW_MODULE, &paths::SYM_MODULE] {
|
||||
if let Some(def_id) = path_to_res(cx, module).opt_def_id() {
|
||||
for item in cx.tcx.item_children(def_id).iter() {
|
||||
for item in cx.tcx.module_children(def_id).iter() {
|
||||
if_chain! {
|
||||
if let Res::Def(DefKind::Const, item_def_id) = item.res;
|
||||
let ty = cx.tcx.type_of(item_def_id);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy_utils"
|
||||
version = "0.1.59"
|
||||
version = "0.1.60"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHasher;
|
|||
use rustc_hir::def::Res;
|
||||
use rustc_hir::HirIdMap;
|
||||
use rustc_hir::{
|
||||
BinOpKind, Block, BodyId, Expr, ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, Guard, HirId,
|
||||
ArrayLen, 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,
|
||||
};
|
||||
|
@ -170,6 +170,14 @@ 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_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 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
}
|
||||
|
||||
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 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
},
|
||||
(&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 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
(&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,9 +399,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, 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 +720,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
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 {
|
||||
|
@ -908,9 +914,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
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);
|
||||
|
@ -955,6 +961,13 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
|
|
@ -76,13 +76,12 @@ use rustc_hir::intravisit::{walk_expr, ErasedMap, FnKind, NestedVisitorMap, Visi
|
|||
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc_hir::LangItem::{OptionNone, ResultErr, ResultOk};
|
||||
use rustc_hir::{
|
||||
def, lang_items, 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, Target,
|
||||
TraitItem, TraitItemKind, TraitRef, TyKind, UnOp,
|
||||
def, lang_items, Arm, ArrayLen, 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,
|
||||
Target, TraitItem, TraitItemKind, TraitRef, TyKind, UnOp,
|
||||
};
|
||||
use rustc_lint::{LateContext, Level, Lint, LintContext};
|
||||
use rustc_middle::hir::exports::Export;
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::hir::place::PlaceBase;
|
||||
use rustc_middle::ty as rustc_ty;
|
||||
|
@ -520,10 +519,21 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
|||
}
|
||||
};
|
||||
}
|
||||
fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Option<&'tcx Export> {
|
||||
tcx.item_children(def_id)
|
||||
.iter()
|
||||
.find(|item| item.ident.name.as_str() == name)
|
||||
fn item_child_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: &str) -> Option<Res> {
|
||||
match tcx.def_kind(def_id) {
|
||||
DefKind::Mod | DefKind::Enum | DefKind::Trait => tcx
|
||||
.module_children(def_id)
|
||||
.iter()
|
||||
.find(|item| item.ident.name.as_str() == name)
|
||||
.map(|child| child.res.expect_non_local()),
|
||||
DefKind::Impl => tcx
|
||||
.associated_item_def_ids(def_id)
|
||||
.iter()
|
||||
.copied()
|
||||
.find(|assoc_def_id| tcx.item_name(*assoc_def_id).as_str() == name)
|
||||
.map(|assoc_def_id| Res::Def(tcx.def_kind(assoc_def_id), assoc_def_id)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn find_primitive(tcx: TyCtxt<'_>, name: &str) -> Option<DefId> {
|
||||
if let Some(&(index, Target::Impl)) = lang_items::ITEM_REFS.get(&Symbol::intern(name)) {
|
||||
|
@ -556,15 +566,12 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
|||
let last = path
|
||||
.iter()
|
||||
.copied()
|
||||
// `get_def_path` seems to generate these empty segments for extern blocks.
|
||||
// We can just ignore them.
|
||||
.filter(|segment| !segment.is_empty())
|
||||
// for each segment, find the child item
|
||||
.try_fold(first, |item, segment| {
|
||||
let def_id = item.res.def_id();
|
||||
.try_fold(first, |res, segment| {
|
||||
let def_id = res.def_id();
|
||||
if let Some(item) = item_child_by_name(tcx, def_id, segment) {
|
||||
Some(item)
|
||||
} else if matches!(item.res, Res::Def(DefKind::Enum | DefKind::Struct, _)) {
|
||||
} else if matches!(res, Res::Def(DefKind::Enum | DefKind::Struct, _)) {
|
||||
// it is not a child item so check inherent impl items
|
||||
tcx.inherent_impls(def_id)
|
||||
.iter()
|
||||
|
@ -573,7 +580,7 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
|||
None
|
||||
}
|
||||
});
|
||||
try_res!(last).res.expect_non_local()
|
||||
try_res!(last).expect_non_local()
|
||||
}
|
||||
|
||||
/// Convenience function to get the `DefId` of a trait by path.
|
||||
|
@ -737,8 +744,8 @@ 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, ArrayLen::Body(len)) => if_chain! {
|
||||
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 {
|
||||
|
|
|
@ -199,7 +199,6 @@ fn check_rvalue<'tcx>(
|
|||
}
|
||||
},
|
||||
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) | Rvalue::ShallowInitBox(_, _) => Ok(()),
|
||||
Rvalue::NullaryOp(NullOp::Box, _) => Err((span, "heap allocations are not allowed in const fn".into())),
|
||||
Rvalue::UnaryOp(_, operand) => {
|
||||
let ty = operand.ty(body, tcx);
|
||||
if ty.is_integral() || ty.is_bool() {
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2021-12-30"
|
||||
channel = "nightly-2022-01-13"
|
||||
components = ["cargo", "llvm-tools-preview", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
error: invalid path
|
||||
--> $DIR/invalid_paths.rs:15:5
|
||||
|
|
||||
LL | pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::invalid-paths` implied by `-D warnings`
|
||||
|
||||
error: invalid path
|
||||
--> $DIR/invalid_paths.rs:18:5
|
||||
|
|
||||
LL | pub const BAD_CRATE_PATH: [&str; 2] = ["bad", "path"];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::invalid-paths` implied by `-D warnings`
|
||||
|
||||
error: invalid path
|
||||
--> $DIR/invalid_paths.rs:21:5
|
||||
|
@ -12,5 +18,5 @@ error: invalid path
|
|||
LL | pub const BAD_MOD_PATH: [&str; 2] = ["std", "xxx"];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -40,7 +40,7 @@ mod a {
|
|||
}
|
||||
}
|
||||
|
||||
// issue #7015, ICE due to calling `item_children` with local `DefId`
|
||||
// issue #7015, ICE due to calling `module_children` with local `DefId`
|
||||
#[macro_use]
|
||||
use a as b;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ mod a {
|
|||
}
|
||||
}
|
||||
|
||||
// issue #7015, ICE due to calling `item_children` with local `DefId`
|
||||
// issue #7015, ICE due to calling `module_children` with local `DefId`
|
||||
#[macro_use]
|
||||
use a as b;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ fn main() {
|
|||
1_234.123_f32,
|
||||
1.123_4_f32,
|
||||
);
|
||||
let _bad = (0b11_0110_i64, 0xcafe_babe_usize, 123_456_f32, 1.234_567_f32);
|
||||
let _bad = (0b11_0110_i64, 0x1234_5678_usize, 123_456_f32, 1.234_567_f32);
|
||||
let _good_sci = 1.1234e1;
|
||||
let _bad_sci = 1.123_456e1;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ fn main() {
|
|||
1_234.123_f32,
|
||||
1.123_4_f32,
|
||||
);
|
||||
let _bad = (0b110110_i64, 0xcafebabe_usize, 123456_f32, 1.234567_f32);
|
||||
let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
|
||||
let _good_sci = 1.1234e1;
|
||||
let _bad_sci = 1.123456e1;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ LL | 0x1_234_567,
|
|||
error: long literal lacking separators
|
||||
--> $DIR/unreadable_literal.rs:33:17
|
||||
|
|
||||
LL | let _bad = (0b110110_i64, 0xcafebabe_usize, 123456_f32, 1.234567_f32);
|
||||
LL | let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
|
||||
| ^^^^^^^^^^^^ help: consider: `0b11_0110_i64`
|
||||
|
|
||||
= note: `-D clippy::unreadable-literal` implied by `-D warnings`
|
||||
|
@ -17,19 +17,19 @@ LL | let _bad = (0b110110_i64, 0xcafebabe_usize, 123456_f32, 1.234567_f32);
|
|||
error: long literal lacking separators
|
||||
--> $DIR/unreadable_literal.rs:33:31
|
||||
|
|
||||
LL | let _bad = (0b110110_i64, 0xcafebabe_usize, 123456_f32, 1.234567_f32);
|
||||
| ^^^^^^^^^^^^^^^^ help: consider: `0xcafe_babe_usize`
|
||||
LL | let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
|
||||
| ^^^^^^^^^^^^^^^^ help: consider: `0x1234_5678_usize`
|
||||
|
||||
error: long literal lacking separators
|
||||
--> $DIR/unreadable_literal.rs:33:49
|
||||
|
|
||||
LL | let _bad = (0b110110_i64, 0xcafebabe_usize, 123456_f32, 1.234567_f32);
|
||||
LL | let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
|
||||
| ^^^^^^^^^^ help: consider: `123_456_f32`
|
||||
|
||||
error: long literal lacking separators
|
||||
--> $DIR/unreadable_literal.rs:33:61
|
||||
|
|
||||
LL | let _bad = (0b110110_i64, 0xcafebabe_usize, 123456_f32, 1.234567_f32);
|
||||
LL | let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
|
||||
| ^^^^^^^^^^^^ help: consider: `1.234_567_f32`
|
||||
|
||||
error: long literal lacking separators
|
||||
|
|
Loading…
Reference in a new issue