Merge commit '7901289135' into clippy-subtree-update

This commit is contained in:
Philipp Krones 2024-09-24 11:58:04 +02:00
parent 249210e8d8
commit b61fcbee76
566 changed files with 7442 additions and 2576 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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)`.

View file

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

View file

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

View file

@ -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] = &[

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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