Auto merge of #8272 - flip1995:rustup, r=flip1995

Rustup

r? `@ghost`

changelog: none
This commit is contained in:
bors 2022-01-13 11:55:36 +00:00
commit 97a5daa659
27 changed files with 139 additions and 93 deletions

View file

@ -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"

View file

@ -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"] }

View file

@ -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()

View file

@ -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 }
});

View file

@ -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 {

View file

@ -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) {

View file

@ -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),

View file

@ -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(..))
}

View file

@ -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 => "(..)",

View file

@ -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();

View file

@ -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);

View file

@ -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

View file

@ -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) => {

View file

@ -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);

View file

@ -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);

View file

@ -1,6 +1,6 @@
[package]
name = "clippy_utils"
version = "0.1.59"
version = "0.1.60"
edition = "2021"
publish = false

View file

@ -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));

View file

@ -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 {

View file

@ -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() {

View file

@ -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"]

View file

@ -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

View file

@ -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 {

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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