Merge commit '7901289135' into clippy-subtree-update
This commit is contained in:
parent
249210e8d8
commit
b61fcbee76
566 changed files with 7442 additions and 2576 deletions
|
|
@ -242,13 +242,16 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
|
|||
}
|
||||
|
||||
fn eq_coroutine_kind(a: Option<CoroutineKind>, b: Option<CoroutineKind>) -> bool {
|
||||
match (a, b) {
|
||||
matches!(
|
||||
(a, b),
|
||||
(Some(CoroutineKind::Async { .. }), Some(CoroutineKind::Async { .. }))
|
||||
| (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. }))
|
||||
| (Some(CoroutineKind::AsyncGen { .. }), Some(CoroutineKind::AsyncGen { .. }))
|
||||
| (None, None) => true,
|
||||
_ => false,
|
||||
}
|
||||
| (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. }))
|
||||
| (
|
||||
Some(CoroutineKind::AsyncGen { .. }),
|
||||
Some(CoroutineKind::AsyncGen { .. })
|
||||
)
|
||||
| (None, None)
|
||||
)
|
||||
}
|
||||
|
||||
pub fn eq_field(l: &ExprField, r: &ExprField) -> bool {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use core::iter::FusedIterator;
|
||||
use rustc_ast::visit::{walk_attribute, walk_expr, Visitor};
|
||||
use rustc_ast::visit::{Visitor, walk_attribute, walk_expr};
|
||||
use rustc_ast::{Attribute, Expr};
|
||||
use rustc_span::symbol::Ident;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use rustc_lexer::TokenKind;
|
|||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{AdtDef, TyCtxt};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_span::{Span, sym};
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::source::SpanRangeExt;
|
||||
|
|
@ -183,15 +183,15 @@ pub fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool {
|
|||
let mut iter = tokenize_with_text(src);
|
||||
|
||||
// Search for the token sequence [`#`, `[`, `cfg`]
|
||||
while iter.any(|(t, _)| matches!(t, TokenKind::Pound)) {
|
||||
let mut iter = iter.by_ref().skip_while(|(t, _)| {
|
||||
while iter.any(|(t, ..)| matches!(t, TokenKind::Pound)) {
|
||||
let mut iter = iter.by_ref().skip_while(|(t, ..)| {
|
||||
matches!(
|
||||
t,
|
||||
TokenKind::Whitespace | TokenKind::LineComment { .. } | TokenKind::BlockComment { .. }
|
||||
)
|
||||
});
|
||||
if matches!(iter.next(), Some((TokenKind::OpenBracket, _)))
|
||||
&& matches!(iter.next(), Some((TokenKind::Ident, "cfg")))
|
||||
if matches!(iter.next(), Some((TokenKind::OpenBracket, ..)))
|
||||
&& matches!(iter.next(), Some((TokenKind::Ident, "cfg", _)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@
|
|||
//! code was written, and check if the span contains that text. Note this will only work correctly
|
||||
//! if the span is not from a `macro_rules` based macro.
|
||||
|
||||
use rustc_ast::AttrStyle;
|
||||
use rustc_ast::ast::{AttrKind, Attribute, IntTy, LitIntType, LitKind, StrStyle, TraitObjectSyntax, UintTy};
|
||||
use rustc_ast::token::CommentKind;
|
||||
use rustc_ast::AttrStyle;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{
|
||||
Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, FnRetTy, HirId, Impl,
|
||||
|
|
@ -24,7 +24,7 @@ use rustc_hir::{
|
|||
use rustc_lint::{LateContext, LintContext};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
use rustc_span::symbol::{Ident, kw};
|
||||
use rustc_span::{Span, Symbol};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
#![allow(clippy::float_cmp)]
|
||||
|
||||
use crate::macros::HirNode;
|
||||
use crate::source::{walk_span_to_context, SpanRangeExt};
|
||||
use crate::source::{SpanRangeExt, walk_span_to_context};
|
||||
use crate::{clip, is_direct_expn_of, sext, unsext};
|
||||
|
||||
use rustc_apfloat::ieee::{Half, Quad};
|
||||
use rustc_apfloat::Float;
|
||||
use rustc_apfloat::ieee::{Half, Quad};
|
||||
use rustc_ast::ast::{self, LitFloatType, LitKind};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{BinOp, BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp};
|
||||
use rustc_lexer::tokenize;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::mir::interpret::{alloc_range, Scalar};
|
||||
use rustc_middle::mir::ConstValue;
|
||||
use rustc_middle::mir::interpret::{Scalar, alloc_range};
|
||||
use rustc_middle::ty::{self, FloatTy, IntTy, ParamEnv, ScalarInt, Ty, TyCtxt, TypeckResults, UintTy};
|
||||
use rustc_middle::{bug, mir, span_bug};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{sym, SyntaxContext};
|
||||
use rustc_span::{SyntaxContext, sym};
|
||||
use rustc_target::abi::Size;
|
||||
use std::cell::Cell;
|
||||
use std::cmp::Ordering;
|
||||
|
|
@ -581,7 +581,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
|
|||
}
|
||||
|
||||
fn constant_negate(&self, o: &Constant<'tcx>, ty: Ty<'_>) -> Option<Constant<'tcx>> {
|
||||
use self::Constant::{Int, F32, F64};
|
||||
use self::Constant::{F32, F64, Int};
|
||||
match *o {
|
||||
Int(value) => {
|
||||
let ty::Int(ity) = *ty.kind() else { return None };
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ use crate::ty::{all_predicates_of, is_copy};
|
|||
use crate::visitors::is_const_evaluatable;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::{walk_expr, Visitor};
|
||||
use rustc_hir::intravisit::{Visitor, walk_expr};
|
||||
use rustc_hir::{BinOpKind, Block, Expr, ExprKind, QPath, UnOp};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::adjustment::Adjust;
|
||||
use rustc_span::{sym, Symbol};
|
||||
use rustc_span::{Symbol, sym};
|
||||
use std::{cmp, ops};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@
|
|||
#![deny(clippy::missing_docs_in_private_items)]
|
||||
|
||||
use crate::consts::{ConstEvalCtxt, Constant};
|
||||
use crate::ty::is_type_diagnostic_item;
|
||||
use crate::is_expn_of;
|
||||
use crate::ty::is_type_diagnostic_item;
|
||||
|
||||
use rustc_ast::ast;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::{Arm, Block, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, QPath};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::{sym, symbol, Span};
|
||||
use rustc_span::{Span, sym, symbol};
|
||||
|
||||
/// The essential nodes of a desugared for loop as well as the entire span:
|
||||
/// `for pat in arg { body }` becomes `(pat, arg, body)`. Returns `(pat, arg, body, span)`.
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
use crate::consts::ConstEvalCtxt;
|
||||
use crate::macros::macro_backtrace;
|
||||
use crate::source::{walk_span_to_context, SpanRange, SpanRangeExt};
|
||||
use crate::source::{SpanRange, SpanRangeExt, walk_span_to_context};
|
||||
use crate::tokenize_with_text;
|
||||
use rustc_ast::ast::InlineAsmTemplatePiece;
|
||||
use rustc_data_structures::fx::FxHasher;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::MatchSource::TryDesugar;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::{
|
||||
ArrayLen, 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, Ty, TyKind,
|
||||
};
|
||||
use rustc_lexer::{tokenize, TokenKind};
|
||||
use rustc_lexer::{TokenKind, tokenize};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::TypeckResults;
|
||||
use rustc_span::{sym, BytePos, ExpnKind, MacroKind, Symbol, SyntaxContext};
|
||||
use rustc_span::{BytePos, ExpnKind, MacroKind, Symbol, SyntaxContext, sym};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Range;
|
||||
|
||||
|
|
@ -1194,8 +1194,8 @@ fn eq_span_tokens(
|
|||
&& let Some(rsrc) = right.get_source_range(cx)
|
||||
&& let Some(rsrc) = rsrc.as_str()
|
||||
{
|
||||
let pred = |t: &(_, _)| pred(t.0);
|
||||
let map = |(_, x)| x;
|
||||
let pred = |&(token, ..): &(TokenKind, _, _)| pred(token);
|
||||
let map = |(_, source, _)| source;
|
||||
|
||||
let ltok = tokenize_with_text(lsrc).filter(pred).map(map);
|
||||
let rtok = tokenize_with_text(rsrc).filter(pred).map(map);
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ pub mod visitors;
|
|||
pub use self::attrs::*;
|
||||
pub use self::check_proc_macro::{is_from_proc_macro, is_span_if, is_span_match};
|
||||
pub use self::hir_utils::{
|
||||
both, count_eq, eq_expr_value, hash_expr, hash_stmt, is_bool, over, HirEqInterExpr, SpanlessEq, SpanlessHash,
|
||||
HirEqInterExpr, SpanlessEq, SpanlessHash, both, count_eq, eq_expr_value, hash_expr, hash_stmt, is_bool, over,
|
||||
};
|
||||
|
||||
use core::mem;
|
||||
|
|
@ -94,20 +94,20 @@ use rustc_ast::ast::{self, LitKind, RangeLimits};
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::packed::Pu128;
|
||||
use rustc_data_structures::unhash::UnhashMap;
|
||||
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalModDefId, LOCAL_CRATE};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId, LocalModDefId};
|
||||
use rustc_hir::definitions::{DefPath, DefPathData};
|
||||
use rustc_hir::hir_id::{HirIdMap, HirIdSet};
|
||||
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
|
||||
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
|
||||
use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
|
||||
use rustc_hir::{
|
||||
self as hir, def, Arm, ArrayLen, 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, TyKind, UnOp,
|
||||
self as hir, Arm, ArrayLen, 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,
|
||||
TyKind, UnOp, def,
|
||||
};
|
||||
use rustc_lexer::{tokenize, TokenKind};
|
||||
use rustc_lexer::{TokenKind, tokenize};
|
||||
use rustc_lint::{LateContext, Level, Lint, LintContext};
|
||||
use rustc_middle::hir::place::PlaceBase;
|
||||
use rustc_middle::mir::Const;
|
||||
|
|
@ -120,12 +120,12 @@ use rustc_middle::ty::{
|
|||
};
|
||||
use rustc_span::hygiene::{ExpnKind, MacroKind};
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::symbol::{kw, Ident, Symbol};
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_span::symbol::{Ident, Symbol, kw};
|
||||
use rustc_span::{InnerSpan, Span, sym};
|
||||
use rustc_target::abi::Integer;
|
||||
use visitors::Visitable;
|
||||
|
||||
use crate::consts::{mir_to_const, ConstEvalCtxt, Constant};
|
||||
use crate::consts::{ConstEvalCtxt, Constant, mir_to_const};
|
||||
use crate::higher::Range;
|
||||
use crate::ty::{adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type};
|
||||
use crate::visitors::for_each_expr_without_closures;
|
||||
|
|
@ -263,9 +263,13 @@ pub fn is_res_lang_ctor(cx: &LateContext<'_>, res: Res, lang_item: LangItem) ->
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// Checks if `{ctor_call_id}(...)` is `{enum_item}::{variant_name}(...)`.
|
||||
pub fn is_enum_variant_ctor(cx: &LateContext<'_>, enum_item: Symbol, variant_name: Symbol, ctor_call_id: DefId) -> bool {
|
||||
pub fn is_enum_variant_ctor(
|
||||
cx: &LateContext<'_>,
|
||||
enum_item: Symbol,
|
||||
variant_name: Symbol,
|
||||
ctor_call_id: DefId,
|
||||
) -> bool {
|
||||
let Some(enum_def_id) = cx.tcx.get_diagnostic_item(enum_item) else {
|
||||
return false;
|
||||
};
|
||||
|
|
@ -667,6 +671,17 @@ fn item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Re
|
|||
}
|
||||
}
|
||||
|
||||
/// Finds the crates called `name`, may be multiple due to multiple major versions.
|
||||
pub fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> Vec<Res> {
|
||||
tcx.crates(())
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(move |&num| tcx.crate_name(num) == name)
|
||||
.map(CrateNum::as_def_id)
|
||||
.map(|id| Res::Def(tcx.def_kind(id), id))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Resolves a def path like `std::vec::Vec`.
|
||||
///
|
||||
/// Can return multiple resolutions when there are multiple versions of the same crate, e.g.
|
||||
|
|
@ -677,15 +692,7 @@ fn item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Re
|
|||
///
|
||||
/// This function is expensive and should be used sparingly.
|
||||
pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
|
||||
fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> impl Iterator<Item = DefId> + '_ {
|
||||
tcx.crates(())
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(move |&num| tcx.crate_name(num) == name)
|
||||
.map(CrateNum::as_def_id)
|
||||
}
|
||||
|
||||
let (base, mut path) = match *path {
|
||||
let (base, path) = match *path {
|
||||
[primitive] => {
|
||||
return vec![PrimTy::from_name(Symbol::intern(primitive)).map_or(Res::Err, Res::PrimTy)];
|
||||
},
|
||||
|
|
@ -701,18 +708,25 @@ pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
|
|||
None
|
||||
};
|
||||
|
||||
let starts = find_primitive_impls(tcx, base)
|
||||
.chain(find_crates(tcx, base_sym))
|
||||
let crates = find_primitive_impls(tcx, base)
|
||||
.chain(local_crate)
|
||||
.map(|id| Res::Def(tcx.def_kind(id), id));
|
||||
.map(|id| Res::Def(tcx.def_kind(id), id))
|
||||
.chain(find_crates(tcx, base_sym))
|
||||
.collect();
|
||||
|
||||
let mut resolutions: Vec<Res> = starts.collect();
|
||||
def_path_res_with_base(tcx, crates, path)
|
||||
}
|
||||
|
||||
/// Resolves a def path like `vec::Vec` with the base `std`.
|
||||
///
|
||||
/// This is lighter than [`def_path_res`], and should be called with [`find_crates`] looking up
|
||||
/// items from the same crate repeatedly, although should still be used sparingly.
|
||||
pub fn def_path_res_with_base(tcx: TyCtxt<'_>, mut base: Vec<Res>, mut path: &[&str]) -> Vec<Res> {
|
||||
while let [segment, rest @ ..] = path {
|
||||
path = rest;
|
||||
let segment = Symbol::intern(segment);
|
||||
|
||||
resolutions = resolutions
|
||||
base = base
|
||||
.into_iter()
|
||||
.filter_map(|res| res.opt_def_id())
|
||||
.flat_map(|def_id| {
|
||||
|
|
@ -731,7 +745,7 @@ pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
|
|||
.collect();
|
||||
}
|
||||
|
||||
resolutions
|
||||
base
|
||||
}
|
||||
|
||||
/// Resolves a def path like `std::vec::Vec` to its [`DefId`]s, see [`def_path_res`].
|
||||
|
|
@ -2944,13 +2958,14 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> ExprU
|
|||
}
|
||||
|
||||
/// Tokenizes the input while keeping the text associated with each token.
|
||||
pub fn tokenize_with_text(s: &str) -> impl Iterator<Item = (TokenKind, &str)> {
|
||||
pub fn tokenize_with_text(s: &str) -> impl Iterator<Item = (TokenKind, &str, InnerSpan)> {
|
||||
let mut pos = 0;
|
||||
tokenize(s).map(move |t| {
|
||||
let end = pos + t.len;
|
||||
let range = pos as usize..end as usize;
|
||||
let inner = InnerSpan::new(range.start, range.end);
|
||||
pos = end;
|
||||
(t.kind, s.get(range).unwrap_or_default())
|
||||
(t.kind, s.get(range).unwrap_or_default(), inner)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -2974,8 +2989,8 @@ pub fn span_contains_comment(sm: &SourceMap, span: Span) -> bool {
|
|||
pub fn span_extract_comment(sm: &SourceMap, span: Span) -> String {
|
||||
let snippet = sm.span_to_snippet(span).unwrap_or_default();
|
||||
let res = tokenize_with_text(&snippet)
|
||||
.filter(|(t, _)| matches!(t, TokenKind::BlockComment { .. } | TokenKind::LineComment { .. }))
|
||||
.map(|(_, s)| s)
|
||||
.filter(|(t, ..)| matches!(t, TokenKind::BlockComment { .. } | TokenKind::LineComment { .. }))
|
||||
.map(|(_, s, _)| s)
|
||||
.join("\n");
|
||||
res
|
||||
}
|
||||
|
|
@ -2995,7 +3010,7 @@ pub fn span_find_starting_semi(sm: &SourceMap, span: Span) -> Span {
|
|||
/// pat: Some(a)
|
||||
/// else_body: return None
|
||||
/// ```
|
||||
|
||||
///
|
||||
/// And for this example:
|
||||
/// ```ignore
|
||||
/// let Some(FooBar { a, b }) = ex else { return None };
|
||||
|
|
@ -3005,7 +3020,7 @@ pub fn span_find_starting_semi(sm: &SourceMap, span: Span) -> Span {
|
|||
/// pat: Some(FooBar { a, b })
|
||||
/// else_body: return None
|
||||
/// ```
|
||||
|
||||
///
|
||||
/// We output `Some(a)` in the first instance, and `Some(FooBar { a, b })` in the second, because
|
||||
/// the question mark operator is applicable here. Callers have to check whether we are in a
|
||||
/// constant or not.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(clippy::similar_names)] // `expr` and `expn`
|
||||
|
||||
use crate::visitors::{for_each_expr_without_closures, Descend};
|
||||
use crate::visitors::{Descend, for_each_expr_without_closures};
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use rustc_ast::{FormatArgs, FormatArgument, FormatPlaceholder};
|
||||
|
|
@ -10,7 +10,7 @@ use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath};
|
|||
use rustc_lint::LateContext;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::hygiene::{self, MacroKind, SyntaxContext};
|
||||
use rustc_span::{sym, BytePos, ExpnData, ExpnId, ExpnKind, Span, SpanData, Symbol};
|
||||
use rustc_span::{BytePos, ExpnData, ExpnId, ExpnKind, Span, SpanData, Symbol, sym};
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
const FORMAT_MACRO_DIAG_ITEMS: &[Symbol] = &[
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use rustc_hir::{Expr, HirId};
|
|||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
|
||||
use rustc_middle::mir::{
|
||||
traversal, BasicBlock, Body, InlineAsmOperand, Local, Location, Place, StatementKind, TerminatorKind, START_BLOCK,
|
||||
BasicBlock, Body, InlineAsmOperand, Local, Location, Place, START_BLOCK, StatementKind, TerminatorKind, traversal,
|
||||
};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
|
|
@ -112,14 +112,10 @@ pub fn block_in_cycle(body: &Body<'_>, block: BasicBlock) -> bool {
|
|||
|
||||
/// Convenience wrapper around `visit_local_usage`.
|
||||
pub fn used_exactly_once(mir: &Body<'_>, local: Local) -> Option<bool> {
|
||||
visit_local_usage(
|
||||
&[local],
|
||||
mir,
|
||||
Location {
|
||||
block: START_BLOCK,
|
||||
statement_index: 0,
|
||||
},
|
||||
)
|
||||
visit_local_usage(&[local], mir, Location {
|
||||
block: START_BLOCK,
|
||||
statement_index: 0,
|
||||
})
|
||||
.map(|mut vec| {
|
||||
let LocalUsage { local_use_locs, .. } = vec.remove(0);
|
||||
let mut locations = local_use_locs
|
||||
|
|
|
|||
|
|
@ -29,7 +29,11 @@ pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"];
|
|||
pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];
|
||||
|
||||
// Paths in `core`/`alloc`/`std`. This should be avoided and cleaned up by adding diagnostic items.
|
||||
// ... none currently!
|
||||
pub const ABORT: [&str; 3] = ["std", "process", "abort"];
|
||||
pub const CHILD: [&str; 3] = ["std", "process", "Child"];
|
||||
pub const CHILD_ID: [&str; 4] = ["std", "process", "Child", "id"];
|
||||
pub const CHILD_KILL: [&str; 4] = ["std", "process", "Child", "kill"];
|
||||
pub const PANIC_ANY: [&str; 3] = ["std", "panic", "panic_any"];
|
||||
|
||||
// Paths in clippy itself
|
||||
pub const MSRV: [&str; 3] = ["clippy_config", "msrvs", "Msrv"];
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::source::snippet;
|
||||
use crate::visitors::{for_each_expr_without_closures, Descend};
|
||||
use crate::visitors::{Descend, for_each_expr_without_closures};
|
||||
use crate::{path_to_local_id, strip_pat_refs};
|
||||
use core::ops::ControlFlow;
|
||||
use rustc_hir::{Body, BodyId, ExprKind, HirId, PatKind};
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ use rustc_middle::mir::{
|
|||
use rustc_middle::traits::{BuiltinImplSource, ImplSource, ObligationCause};
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::{self, GenericArgKind, TraitRef, Ty, TyCtxt};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_trait_selection::traits::{ObligationCtxt, SelectionContext};
|
||||
use std::borrow::Cow;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ use rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource};
|
|||
use rustc_lint::{EarlyContext, LateContext};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::source_map::{original_sp, SourceMap};
|
||||
use rustc_span::source_map::{SourceMap, original_sp};
|
||||
use rustc_span::{
|
||||
hygiene, BytePos, FileNameDisplayPreference, Pos, SourceFile, SourceFileAndLine, Span, SpanData, SyntaxContext,
|
||||
DUMMY_SP,
|
||||
BytePos, DUMMY_SP, FileNameDisplayPreference, Pos, SourceFile, SourceFileAndLine, Span, SpanData, SyntaxContext,
|
||||
hygiene,
|
||||
};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
|
|
@ -666,39 +666,6 @@ pub fn walk_span_to_context(span: Span, outer: SyntaxContext) -> Option<Span> {
|
|||
(outer_span.ctxt() == outer).then_some(outer_span)
|
||||
}
|
||||
|
||||
/// Removes block comments from the given `Vec` of lines.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// without_block_comments(vec!["/*", "foo", "*/"]);
|
||||
/// // => vec![]
|
||||
///
|
||||
/// without_block_comments(vec!["bar", "/*", "foo", "*/"]);
|
||||
/// // => vec!["bar"]
|
||||
/// ```
|
||||
pub fn without_block_comments(lines: Vec<&str>) -> Vec<&str> {
|
||||
let mut without = vec![];
|
||||
|
||||
let mut nest_level = 0;
|
||||
|
||||
for line in lines {
|
||||
if line.contains("/*") {
|
||||
nest_level += 1;
|
||||
continue;
|
||||
} else if line.contains("*/") {
|
||||
nest_level -= 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if nest_level == 0 {
|
||||
without.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
without
|
||||
}
|
||||
|
||||
/// Trims the whitespace from the start and the end of the span.
|
||||
pub fn trim_span(sm: &SourceMap, span: Span) -> Span {
|
||||
let data = span.data();
|
||||
|
|
@ -758,15 +725,12 @@ pub fn str_literal_to_char_literal(
|
|||
&snip[1..(snip.len() - 1)]
|
||||
};
|
||||
|
||||
let hint = format!(
|
||||
"'{}'",
|
||||
match ch {
|
||||
"'" => "\\'",
|
||||
r"\" => "\\\\",
|
||||
"\\\"" => "\"", // no need to escape `"` in `'"'`
|
||||
_ => ch,
|
||||
}
|
||||
);
|
||||
let hint = format!("'{}'", match ch {
|
||||
"'" => "\\'",
|
||||
r"\" => "\\\\",
|
||||
"\\\"" => "\"", // no need to escape `"` in `'"'`
|
||||
_ => ch,
|
||||
});
|
||||
|
||||
Some(hint)
|
||||
} else {
|
||||
|
|
@ -776,7 +740,7 @@ pub fn str_literal_to_char_literal(
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{reindent_multiline, without_block_comments};
|
||||
use super::reindent_multiline;
|
||||
|
||||
#[test]
|
||||
fn test_reindent_multiline_single_line() {
|
||||
|
|
@ -844,29 +808,4 @@ mod test {
|
|||
z
|
||||
}".into(), true, Some(8)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_without_block_comments_lines_without_block_comments() {
|
||||
let result = without_block_comments(vec!["/*", "", "*/"]);
|
||||
println!("result: {result:?}");
|
||||
assert!(result.is_empty());
|
||||
|
||||
let result = without_block_comments(vec!["", "/*", "", "*/", "#[crate_type = \"lib\"]", "/*", "", "*/", ""]);
|
||||
assert_eq!(result, vec!["", "#[crate_type = \"lib\"]", ""]);
|
||||
|
||||
let result = without_block_comments(vec!["/* rust", "", "*/"]);
|
||||
assert!(result.is_empty());
|
||||
|
||||
let result = without_block_comments(vec!["/* one-line comment */"]);
|
||||
assert!(result.is_empty());
|
||||
|
||||
let result = without_block_comments(vec!["/* nested", "/* multi-line", "comment", "*/", "test", "*/"]);
|
||||
assert!(result.is_empty());
|
||||
|
||||
let result = without_block_comments(vec!["/* nested /* inline /* comment */ test */ */"]);
|
||||
assert!(result.is_empty());
|
||||
|
||||
let result = without_block_comments(vec!["foo", "bar", "baz"]);
|
||||
assert_eq!(result, vec!["foo", "bar", "baz"]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -370,9 +370,11 @@ mod test {
|
|||
assert_eq!(camel_case_split("AbcDef"), vec!["Abc", "Def"]);
|
||||
assert_eq!(camel_case_split("Abc"), vec!["Abc"]);
|
||||
assert_eq!(camel_case_split("abcDef"), vec!["abc", "Def"]);
|
||||
assert_eq!(
|
||||
camel_case_split("\u{f6}\u{f6}AabABcd"),
|
||||
vec!["\u{f6}\u{f6}", "Aab", "A", "Bcd"]
|
||||
);
|
||||
assert_eq!(camel_case_split("\u{f6}\u{f6}AabABcd"), vec![
|
||||
"\u{f6}\u{f6}",
|
||||
"Aab",
|
||||
"A",
|
||||
"Bcd"
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,8 +180,10 @@ impl<'a> Sugg<'a> {
|
|||
) -> Self {
|
||||
use rustc_ast::ast::RangeLimits;
|
||||
|
||||
let mut snippet = |span: Span| snippet_with_context(cx, span, ctxt, default, app).0;
|
||||
|
||||
match expr.kind {
|
||||
_ if expr.span.ctxt() != ctxt => Sugg::NonParen(snippet_with_context(cx, expr.span, ctxt, default, app).0),
|
||||
_ if expr.span.ctxt() != ctxt => Sugg::NonParen(snippet(expr.span)),
|
||||
ast::ExprKind::AddrOf(..)
|
||||
| ast::ExprKind::Closure { .. }
|
||||
| ast::ExprKind::If(..)
|
||||
|
|
@ -224,46 +226,38 @@ impl<'a> Sugg<'a> {
|
|||
| ast::ExprKind::While(..)
|
||||
| ast::ExprKind::Await(..)
|
||||
| ast::ExprKind::Err(_)
|
||||
| ast::ExprKind::Dummy => Sugg::NonParen(snippet_with_context(cx, expr.span, ctxt, default, app).0),
|
||||
| ast::ExprKind::Dummy => Sugg::NonParen(snippet(expr.span)),
|
||||
ast::ExprKind::Range(ref lhs, ref rhs, RangeLimits::HalfOpen) => Sugg::BinOp(
|
||||
AssocOp::DotDot,
|
||||
lhs.as_ref().map_or("".into(), |lhs| {
|
||||
snippet_with_context(cx, lhs.span, ctxt, default, app).0
|
||||
}),
|
||||
rhs.as_ref().map_or("".into(), |rhs| {
|
||||
snippet_with_context(cx, rhs.span, ctxt, default, app).0
|
||||
}),
|
||||
lhs.as_ref().map_or("".into(), |lhs| snippet(lhs.span)),
|
||||
rhs.as_ref().map_or("".into(), |rhs| snippet(rhs.span)),
|
||||
),
|
||||
ast::ExprKind::Range(ref lhs, ref rhs, RangeLimits::Closed) => Sugg::BinOp(
|
||||
AssocOp::DotDotEq,
|
||||
lhs.as_ref().map_or("".into(), |lhs| {
|
||||
snippet_with_context(cx, lhs.span, ctxt, default, app).0
|
||||
}),
|
||||
rhs.as_ref().map_or("".into(), |rhs| {
|
||||
snippet_with_context(cx, rhs.span, ctxt, default, app).0
|
||||
}),
|
||||
lhs.as_ref().map_or("".into(), |lhs| snippet(lhs.span)),
|
||||
rhs.as_ref().map_or("".into(), |rhs| snippet(rhs.span)),
|
||||
),
|
||||
ast::ExprKind::Assign(ref lhs, ref rhs, _) => Sugg::BinOp(
|
||||
AssocOp::Assign,
|
||||
snippet_with_context(cx, lhs.span, ctxt, default, app).0,
|
||||
snippet_with_context(cx, rhs.span, ctxt, default, app).0,
|
||||
snippet(lhs.span),
|
||||
snippet(rhs.span),
|
||||
),
|
||||
ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => Sugg::BinOp(
|
||||
astbinop2assignop(op),
|
||||
snippet_with_context(cx, lhs.span, ctxt, default, app).0,
|
||||
snippet_with_context(cx, rhs.span, ctxt, default, app).0,
|
||||
snippet(lhs.span),
|
||||
snippet(rhs.span),
|
||||
),
|
||||
ast::ExprKind::Binary(op, ref lhs, ref rhs) => Sugg::BinOp(
|
||||
AssocOp::from_ast_binop(op.node),
|
||||
snippet_with_context(cx, lhs.span, ctxt, default, app).0,
|
||||
snippet_with_context(cx, rhs.span, ctxt, default, app).0,
|
||||
snippet(lhs.span),
|
||||
snippet(rhs.span),
|
||||
),
|
||||
ast::ExprKind::Cast(ref lhs, ref ty) |
|
||||
//FIXME(chenyukang), remove this after type ascription is removed from AST
|
||||
ast::ExprKind::Type(ref lhs, ref ty) => Sugg::BinOp(
|
||||
AssocOp::As,
|
||||
snippet_with_context(cx, lhs.span, ctxt, default, app).0,
|
||||
snippet_with_context(cx, ty.span, ctxt, default, app).0,
|
||||
snippet(lhs.span),
|
||||
snippet(ty.span),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_hir::{Expr, FnDecl, LangItem, Safety, TyKind};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::mir::interpret::Scalar;
|
||||
use rustc_middle::mir::ConstValue;
|
||||
use rustc_middle::mir::interpret::Scalar;
|
||||
use rustc_middle::traits::EvaluationResult;
|
||||
use rustc_middle::ty::layout::ValidityRequirement;
|
||||
use rustc_middle::ty::{
|
||||
|
|
@ -22,7 +22,7 @@ use rustc_middle::ty::{
|
|||
TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,
|
||||
};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
|
||||
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
|
||||
|
|
@ -606,10 +606,13 @@ fn is_uninit_value_valid_for_ty_fallback<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t
|
|||
ty::Tuple(types) => types.iter().all(|ty| is_uninit_value_valid_for_ty(cx, ty)),
|
||||
// Unions are always fine right now.
|
||||
// This includes MaybeUninit, the main way people use uninitialized memory.
|
||||
// For ADTs, we could look at all fields just like for tuples, but that's potentially
|
||||
// exponential, so let's avoid doing that for now. Code doing that is sketchy enough to
|
||||
// just use an `#[allow()]`.
|
||||
ty::Adt(adt, _) => adt.is_union(),
|
||||
ty::Adt(adt, _) if adt.is_union() => true,
|
||||
// Types (e.g. `UnsafeCell<MaybeUninit<T>>`) that recursively contain only types that can be uninit
|
||||
// can themselves be uninit too.
|
||||
// This purposefully ignores enums as they may have a discriminant that can't be uninit.
|
||||
ty::Adt(adt, args) if adt.is_struct() => adt
|
||||
.all_fields()
|
||||
.all(|field| is_uninit_value_valid_for_ty(cx, field.ty(cx.tcx, args))),
|
||||
// For the rest, conservatively assume that they cannot be uninit.
|
||||
_ => false,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,14 +14,14 @@
|
|||
use crate::def_path_res;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::{walk_qpath, walk_ty, Visitor};
|
||||
use rustc_hir::intravisit::{Visitor, walk_qpath, walk_ty};
|
||||
use rustc_hir::{self as hir, Expr, ExprKind, GenericArgs, HirId, Node, PathSegment, QPath, TyKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{self, AdtDef, GenericArgKind, Ty};
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
mod certainty;
|
||||
use certainty::{join, meet, Certainty, Meet};
|
||||
use certainty::{Certainty, Meet, join, meet};
|
||||
|
||||
pub fn expr_type_is_certain(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
expr_type_certainty(cx, expr).is_certain()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::visitors::{for_each_expr, for_each_expr_without_closures, Descend, Visitable};
|
||||
use crate::visitors::{Descend, Visitable, for_each_expr, for_each_expr_without_closures};
|
||||
use crate::{self as utils, get_enclosing_loop_or_multi_call_closure};
|
||||
use core::ops::ControlFlow;
|
||||
use hir::def::Res;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
use crate::ty::needs_ordered_drop;
|
||||
use crate::{get_enclosing_block, path_to_local_id};
|
||||
use core::ops::ControlFlow;
|
||||
use rustc_ast::visit::{try_visit, VisitorResult};
|
||||
use rustc_ast::visit::{VisitorResult, try_visit};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||
use rustc_hir::intravisit::{self, walk_block, walk_expr, Visitor};
|
||||
use rustc_hir::intravisit::{self, Visitor, walk_block, walk_expr};
|
||||
use rustc_hir::{
|
||||
AnonConst, Arm, Block, BlockCheckMode, Body, BodyId, Expr, ExprKind, HirId, ItemId, ItemKind, LetExpr, Pat, QPath,
|
||||
Safety, Stmt, UnOp, UnsafeSource,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue