Merge remote-tracking branch 'upstream/master' into only_used_in_recursion

# Conflicts:
#	clippy_lints/src/lib.rs
This commit is contained in:
Jaeyong Sung 2022-02-13 02:43:23 +09:00
commit 9055f34b71
No known key found for this signature in database
GPG key ID: 2B86898CCB2A5486
34 changed files with 202 additions and 141 deletions

View file

@ -1,11 +1,11 @@
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
use clippy_utils::source::snippet_opt;
use rustc_ast::ast;
use rustc_ast::tokenstream::TokenStream;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::macros::root_macro_call_first_node;
use clippy_utils::source::snippet_with_applicability;
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span;
use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
@ -15,14 +15,6 @@ declare_clippy_lint! {
/// `dbg!` macro is intended as a debugging tool. It
/// should not be in version control.
///
/// ### Known problems
/// * The lint level is unaffected by crate attributes. The level can still
/// be set for functions, modules and other items. To change the level for
/// the entire crate, please use command line flags. More information and a
/// configuration example can be found in [clippy#6610].
///
/// [clippy#6610]: https://github.com/rust-lang/rust-clippy/issues/6610#issuecomment-977120558
///
/// ### Example
/// ```rust,ignore
/// // Bad
@ -39,37 +31,52 @@ declare_clippy_lint! {
declare_lint_pass!(DbgMacro => [DBG_MACRO]);
impl EarlyLintPass for DbgMacro {
fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::MacCall) {
if mac.path == sym!(dbg) {
if let Some(sugg) = tts_span(mac.args.inner_tokens()).and_then(|span| snippet_opt(cx, span)) {
span_lint_and_sugg(
cx,
DBG_MACRO,
mac.span(),
"`dbg!` macro is intended as a debugging tool",
"ensure to avoid having uses of it in version control",
sugg,
Applicability::MaybeIncorrect,
);
} else {
span_lint_and_help(
cx,
DBG_MACRO,
mac.span(),
"`dbg!` macro is intended as a debugging tool",
None,
"ensure to avoid having uses of it in version control",
);
}
impl LateLintPass<'_> for DbgMacro {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
if cx.tcx.is_diagnostic_item(sym::dbg_macro, macro_call.def_id) {
let mut applicability = Applicability::MachineApplicable;
let suggestion = match expr.peel_drop_temps().kind {
// dbg!()
ExprKind::Block(_, _) => String::new(),
// dbg!(1)
ExprKind::Match(val, ..) => {
snippet_with_applicability(cx, val.span.source_callsite(), "..", &mut applicability).to_string()
},
// dbg!(2, 3)
ExprKind::Tup(
[
Expr {
kind: ExprKind::Match(first, ..),
..
},
..,
Expr {
kind: ExprKind::Match(last, ..),
..
},
],
) => {
let snippet = snippet_with_applicability(
cx,
first.span.source_callsite().to(last.span.source_callsite()),
"..",
&mut applicability,
);
format!("({snippet})")
},
_ => return,
};
span_lint_and_sugg(
cx,
DBG_MACRO,
macro_call.span,
"`dbg!` macro is intended as a debugging tool",
"ensure to avoid having uses of it in version control",
suggestion,
applicability,
);
}
}
}
// Get span enclosing entire the token stream.
fn tts_span(tts: TokenStream) -> Option<Span> {
let mut cursor = tts.into_trees();
let first = cursor.next()?.span();
let span = cursor.last().map_or(first, |tree| first.to(tree.span()));
Some(span)
}

View file

@ -12,7 +12,7 @@ use rustc_hir::{
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
use rustc_middle::ty::{self, Ty, TyCtxt, TyS, TypeckResults};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeckResults};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{symbol::sym, Span};
@ -448,7 +448,7 @@ fn try_parse_ref_op<'tcx>(
// the reference.
fn deref_method_same_type(result_ty: Ty<'_>, arg_ty: Ty<'_>) -> bool {
match (result_ty.kind(), arg_ty.kind()) {
(ty::Ref(_, result_ty, _), ty::Ref(_, arg_ty, _)) => TyS::same_type(result_ty, arg_ty),
(ty::Ref(_, result_ty, _), ty::Ref(_, arg_ty, _)) => result_ty == arg_ty,
// The result type for a deref method is always a reference
// Not matching the previous pattern means the argument type is not a reference

View file

@ -8,7 +8,7 @@ use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind}
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::hir::nested_filter;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{Ty, TyS, TypeckResults};
use rustc_middle::ty::{Ty, TypeckResults};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span;
use rustc_span::symbol::sym;
@ -345,7 +345,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't
if let TyKind::Path(QPath::Resolved(None, ty_path)) = ty.kind;
if let Some(ty_did) = ty_path.res.opt_def_id();
then {
if !TyS::same_type(self.target.ty(), self.maybe_typeck_results.unwrap().expr_ty(e)) {
if self.target.ty() != self.maybe_typeck_results.unwrap().expr_ty(e) {
return;
}

View file

@ -4,7 +4,7 @@ use clippy_utils::higher::IfLet;
use clippy_utils::ty::is_copy;
use clippy_utils::{is_expn_of, is_lint_allowed, meets_msrv, msrvs, path_to_local};
use if_chain::if_chain;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor};
@ -92,9 +92,9 @@ impl<'tcx> LateLintPass<'tcx> for IndexRefutableSlice {
extract_msrv_attr!(LateContext);
}
fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxHashMap<hir::HirId, SliceLintInformation> {
fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap<hir::HirId, SliceLintInformation> {
let mut removed_pat: FxHashSet<hir::HirId> = FxHashSet::default();
let mut slices: FxHashMap<hir::HirId, SliceLintInformation> = FxHashMap::default();
let mut slices: FxIndexMap<hir::HirId, SliceLintInformation> = FxIndexMap::default();
pat.walk_always(|pat| {
if let hir::PatKind::Binding(binding, value_hir_id, ident, sub_pat) = pat.kind {
// We'll just ignore mut and ref mut for simplicity sake right now
@ -208,10 +208,10 @@ impl SliceLintInformation {
fn filter_lintable_slices<'a, 'tcx>(
cx: &'a LateContext<'tcx>,
slice_lint_info: FxHashMap<hir::HirId, SliceLintInformation>,
slice_lint_info: FxIndexMap<hir::HirId, SliceLintInformation>,
max_suggested_slice: u64,
scope: &'tcx hir::Expr<'tcx>,
) -> FxHashMap<hir::HirId, SliceLintInformation> {
) -> FxIndexMap<hir::HirId, SliceLintInformation> {
let mut visitor = SliceIndexLintingVisitor {
cx,
slice_lint_info,
@ -225,7 +225,7 @@ fn filter_lintable_slices<'a, 'tcx>(
struct SliceIndexLintingVisitor<'a, 'tcx> {
cx: &'a LateContext<'tcx>,
slice_lint_info: FxHashMap<hir::HirId, SliceLintInformation>,
slice_lint_info: FxIndexMap<hir::HirId, SliceLintInformation>,
max_suggested_slice: u64,
}

View file

@ -10,7 +10,7 @@ use rustc_hir::{
ItemKind, Mutability, Node, TraitItemRef, TyKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, AssocKind, FnSig, Ty, TyS};
use rustc_middle::ty::{self, AssocKind, FnSig, Ty};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{
source_map::{Span, Spanned, Symbol},
@ -265,7 +265,7 @@ impl LenOutput<'_> {
(_, &ty::Bool) => true,
(Self::Option(id), &ty::Adt(adt, subs)) if id == adt.did => subs.type_at(0).is_bool(),
(Self::Result(id, err_ty), &ty::Adt(adt, subs)) if id == adt.did => {
subs.type_at(0).is_bool() && TyS::same_type(subs.type_at(1), err_ty)
subs.type_at(0).is_bool() && subs.type_at(1) == err_ty
},
_ => false,
}

View file

@ -278,7 +278,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
LintId::of(transmute::TRANSMUTE_NUM_TO_BYTES),
LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR),
LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
LintId::of(transmute::WRONG_TRANSMUTE),
LintId::of(transmuting_null::TRANSMUTING_NULL),

View file

@ -58,7 +58,6 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve
LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
LintId::of(swap::ALMOST_SWAPPED),
LintId::of(to_string_in_display::TO_STRING_IN_DISPLAY),
LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR),
LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
LintId::of(transmute::WRONG_TRANSMUTE),
LintId::of(transmuting_null::TRANSMUTING_NULL),

View file

@ -26,6 +26,7 @@ store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
LintId::of(strings::STRING_LIT_AS_BYTES),
LintId::of(suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS),
LintId::of(trailing_empty_array::TRAILING_EMPTY_ARRAY),
LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR),
LintId::of(transmute::USELESS_TRANSMUTE),
LintId::of(use_self::USE_SELF),
])

View file

@ -18,6 +18,8 @@
#![warn(rust_2018_idioms, unused_lifetimes)]
// warn on rustc internal lints
#![warn(rustc::internal)]
// Disable this rustc lint for now, as it was also done in rustc
#![allow(rustc::potential_query_instability)]
// FIXME: switch to something more ergonomic here, once available.
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
@ -431,7 +433,6 @@ pub fn register_pre_expansion_lints(store: &mut rustc_lint::LintStore, sess: &Se
store.register_pre_expansion_pass(|| Box::new(write::Write::default()));
store.register_pre_expansion_pass(move || Box::new(attrs::EarlyAttributes { msrv }));
store.register_pre_expansion_pass(|| Box::new(dbg_macro::DbgMacro));
}
#[doc(hidden)]
@ -864,6 +865,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(move || Box::new(manual_bits::ManualBits::new(msrv)));
store.register_late_pass(|| Box::new(default_union_representation::DefaultUnionRepresentation));
store.register_late_pass(|| Box::new(only_used_in_recursion::OnlyUsedInRecursion));
store.register_late_pass(|| Box::new(dbg_macro::DbgMacro));
// add lints here, do not remove this comment, it's used in `new_lint`
}

View file

@ -5,13 +5,12 @@ use clippy_utils::source::snippet_with_applicability;
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_middle::ty::TyS;
use rustc_span::symbol::sym;
pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr<'_>) {
let self_ty = cx.typeck_results().expr_ty(self_arg);
let self_ty_adjusted = cx.typeck_results().expr_ty_adjusted(self_arg);
if !(TyS::same_type(self_ty, self_ty_adjusted) && is_trait_method(cx, call_expr, sym::IntoIterator)) {
if !(self_ty == self_ty_adjusted && is_trait_method(cx, call_expr, sym::IntoIterator)) {
return;
}

View file

@ -6,7 +6,7 @@ use clippy_utils::ty::is_type_diagnostic_item;
use rustc_errors::Applicability;
use rustc_hir::{Expr, Mutability};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty, TyS};
use rustc_middle::ty::{self, Ty};
use rustc_span::sym;
pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, arg: &Expr<'_>, method_name: &str) {
@ -22,7 +22,7 @@ pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, arg: &Expr<'_>, m
mutbl: Mutability::Not,
},
);
TyS::same_type(receiver_ty_adjusted, ref_receiver_ty)
receiver_ty_adjusted == ref_receiver_ty
},
_ => false,
};

View file

@ -3,7 +3,6 @@ use clippy_utils::source::snippet;
use clippy_utils::{path_to_local, search_same, SpanlessEq, SpanlessHash};
use rustc_hir::{Arm, Expr, ExprKind, HirId, HirIdMap, HirIdSet, MatchSource, Pat, PatKind};
use rustc_lint::LateContext;
use rustc_middle::ty::TyS;
use std::collections::hash_map::Entry;
use super::MATCH_SAME_ARMS;
@ -32,7 +31,7 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) {
};
// the names technically don't have to match; this makes the lint more conservative
if cx.tcx.hir().name(a_id) == cx.tcx.hir().name(b_id);
if TyS::same_type(cx.typeck_results().expr_ty(a), cx.typeck_results().expr_ty(b));
if cx.typeck_results().expr_ty(a) == cx.typeck_results().expr_ty(b);
if pat_contains_local(lhs.pat, a_id);
if pat_contains_local(rhs.pat, b_id);
then {

View file

@ -8,7 +8,6 @@ use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::{Expr, ExprKind, PatKind, QPath, UnOp};
use rustc_lint::LateContext;
use rustc_middle::ty::TyS;
use rustc_span::source_map::Span;
use rustc_span::symbol::{sym, Symbol};
use std::borrow::Cow;
@ -149,7 +148,7 @@ pub(super) fn check<'tcx>(
if_chain! {
if path_to_local_id(a_path, filter_param_id);
if path_to_local_id(b, map_param_id);
if TyS::same_type(cx.typeck_results().expr_ty_adjusted(a), cx.typeck_results().expr_ty_adjusted(b));
if cx.typeck_results().expr_ty_adjusted(a) == cx.typeck_results().expr_ty_adjusted(b);
then {
return true;
}

View file

@ -6,7 +6,6 @@ use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_middle::ty::TyS;
use rustc_span::sym;
use super::IMPLICIT_CLONE;
@ -19,7 +18,7 @@ pub fn check(cx: &LateContext<'_>, method_name: &str, expr: &hir::Expr<'_>, recv
let input_type = cx.typeck_results().expr_ty(recv);
let (input_type, ref_count) = peel_mid_ty_refs(input_type);
if let Some(ty_name) = input_type.ty_adt_def().map(|adt_def| cx.tcx.item_name(adt_def.did));
if TyS::same_type(return_type, input_type);
if return_type == input_type;
then {
let mut app = Applicability::MachineApplicable;
let recv_snip = snippet_with_context(cx, recv.span, expr.span.ctxt(), "..", &mut app).0;

View file

@ -78,7 +78,7 @@ use rustc_hir::def::Res;
use rustc_hir::{Expr, ExprKind, PrimTy, QPath, TraitItem, TraitItemKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, TraitRef, Ty, TyS};
use rustc_middle::ty::{self, TraitRef, Ty};
use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{sym, Span};
@ -2198,7 +2198,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
}
}
if name == "new" && !TyS::same_type(ret_ty, self_ty) {
if name == "new" && ret_ty != self_ty {
span_lint(
cx,
NEW_RET_NO_SELF,

View file

@ -5,7 +5,7 @@ use rustc_hir as hir;
use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::LangItem::{OptionNone, OptionSome};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, TyS};
use rustc_middle::ty;
use rustc_span::sym;
use super::UNNECESSARY_FILTER_MAP;
@ -33,9 +33,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<
} else if !found_mapping && !mutates_arg {
let in_ty = cx.typeck_results().node_type(body.params[0].hir_id);
match cx.typeck_results().expr_ty(&body.value).kind() {
ty::Adt(adt, subst)
if cx.tcx.is_diagnostic_item(sym::Option, adt.did) && TyS::same_type(in_ty, subst.type_at(0)) =>
{
ty::Adt(adt, subst) if cx.tcx.is_diagnostic_item(sym::Option, adt.did) && in_ty == subst.type_at(0) => {
"filter"
},
_ => return,

View file

@ -4,7 +4,6 @@ use clippy_utils::ty::is_type_diagnostic_item;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::TyS;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::sym;
@ -49,7 +48,7 @@ impl<'tcx> LateLintPass<'tcx> for OptionNeedlessDeref {
if let ExprKind::MethodCall(path, [sub_expr], _) = expr.kind;
let symbol = path.ident.as_str();
if symbol == "as_deref" || symbol == "as_deref_mut";
if TyS::same_type( outer_ty, typeck.expr_ty(sub_expr) );
if outer_ty == typeck.expr_ty(sub_expr);
then{
span_lint_and_sugg(
cx,

View file

@ -6,7 +6,6 @@ use rustc_errors::Applicability;
use rustc_hir::LangItem::{OptionSome, ResultOk};
use rustc_hir::{AsyncGeneratorKind, Block, Body, Expr, ExprKind, GeneratorKind, LangItem, MatchSource, QPath};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::TyS;
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
@ -128,7 +127,7 @@ fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
if expr.span.ctxt() == inner_expr.span.ctxt();
let expr_ty = cx.typeck_results().expr_ty(expr);
let inner_ty = cx.typeck_results().expr_ty(inner_expr);
if TyS::same_type(expr_ty, inner_ty);
if expr_ty == inner_ty;
then {
span_lint_and_sugg(
cx,

View file

@ -8,7 +8,6 @@ use rustc_hir as hir;
use rustc_hir::HirIdSet;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::TyS;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::sym;
@ -103,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
if cx.access_levels.is_reachable(impl_item.def_id);
let self_def_id = cx.tcx.hir().get_parent_item(id);
let self_ty = cx.tcx.type_of(self_def_id);
if TyS::same_type(self_ty, return_ty(cx, id));
if self_ty == return_ty(cx, id);
if let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default);
then {
if self.impling_types.is_none() {

View file

@ -6,7 +6,6 @@ use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::TyS;
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
@ -54,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
if addressee.span.ctxt() == ctxt;
if let ExprKind::Index(indexed, range) = addressee.kind;
if is_type_lang_item(cx, cx.typeck_results().expr_ty_adjusted(range), LangItem::RangeFull);
if TyS::same_type(cx.typeck_results().expr_ty(expr), cx.typeck_results().expr_ty(indexed));
if cx.typeck_results().expr_ty(expr) == cx.typeck_results().expr_ty(indexed);
then {
let mut app = Applicability::MachineApplicable;
let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0;

View file

@ -7,7 +7,7 @@ use if_chain::if_chain;
use rustc_hir::BinOpKind;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, Ty, TyS, TypeAndMut};
use rustc_middle::ty::{self, Ty, TypeAndMut};
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
@ -138,7 +138,7 @@ impl<'tcx> LateLintPass<'tcx> for SizeOfInElementCount {
// Find a size_of call in the count parameter expression and
// check that it's the same type
if let Some(ty_used_for_size_of) = get_size_of_ty(cx, count_expr, false);
if TyS::same_type(pointee_ty, ty_used_for_size_of);
if pointee_ty == ty_used_for_size_of;
then {
span_lint_and_help(
cx,

View file

@ -376,7 +376,7 @@ declare_clippy_lint! {
/// ```
#[clippy::version = "1.60.0"]
pub TRANSMUTE_UNDEFINED_REPR,
correctness,
nursery,
"transmute to or from a type with an undefined representation"
}

View file

@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_middle::ty::subst::{GenericArg, Subst};
use rustc_middle::ty::{self, Ty, TyS, TypeAndMut};
use rustc_middle::ty::{self, Ty, TypeAndMut};
use rustc_span::Span;
#[allow(clippy::too_many_lines)]
@ -16,7 +16,7 @@ pub(super) fn check<'tcx>(
let mut from_ty = cx.tcx.erase_regions(from_ty_orig);
let mut to_ty = cx.tcx.erase_regions(to_ty_orig);
while !TyS::same_type(from_ty, to_ty) {
while from_ty != to_ty {
match reduce_refs(cx, e.span, from_ty, to_ty) {
ReducedTys::FromFatPtr { unsized_ty, .. } => {
span_lint_and_then(
@ -25,7 +25,7 @@ pub(super) fn check<'tcx>(
e.span,
&format!("transmute from `{}` which has an undefined layout", from_ty_orig),
|diag| {
if !TyS::same_type(from_ty_orig.peel_refs(), unsized_ty) {
if from_ty_orig.peel_refs() != unsized_ty {
diag.note(&format!("the contained type `&{}` has an undefined layout", unsized_ty));
}
},
@ -39,7 +39,7 @@ pub(super) fn check<'tcx>(
e.span,
&format!("transmute to `{}` which has an undefined layout", to_ty_orig),
|diag| {
if !TyS::same_type(to_ty_orig.peel_refs(), unsized_ty) {
if to_ty_orig.peel_refs() != unsized_ty {
diag.note(&format!("the contained type `&{}` has an undefined layout", unsized_ty));
}
},
@ -57,7 +57,7 @@ pub(super) fn check<'tcx>(
e.span,
&format!("transmute from `{}` which has an undefined layout", from_ty_orig),
|diag| {
if !TyS::same_type(from_ty_orig.peel_refs(), from_ty) {
if from_ty_orig.peel_refs() != from_ty {
diag.note(&format!("the contained type `{}` has an undefined layout", from_ty));
}
},
@ -82,7 +82,7 @@ pub(super) fn check<'tcx>(
e.span,
&format!("transmute to `{}` which has an undefined layout", to_ty_orig),
|diag| {
if !TyS::same_type(to_ty_orig.peel_refs(), to_ty) {
if to_ty_orig.peel_refs() != to_ty {
diag.note(&format!("the contained type `{}` has an undefined layout", to_ty));
}
},
@ -101,9 +101,7 @@ pub(super) fn check<'tcx>(
to_ty: to_sub_ty,
} => match (reduce_ty(cx, from_sub_ty), reduce_ty(cx, to_sub_ty)) {
(ReducedTy::IntArray, _) | (_, ReducedTy::IntArray) => return false,
(ReducedTy::UnorderedFields(from_ty), ReducedTy::UnorderedFields(to_ty))
if !TyS::same_type(from_ty, to_ty) =>
{
(ReducedTy::UnorderedFields(from_ty), ReducedTy::UnorderedFields(to_ty)) if from_ty != to_ty => {
span_lint_and_then(
cx,
TRANSMUTE_UNDEFINED_REPR,
@ -121,10 +119,10 @@ pub(super) fn check<'tcx>(
cx.tcx.item_name(from_def.did)
));
} else {
if !TyS::same_type(from_ty_orig.peel_refs(), from_ty) {
if from_ty_orig.peel_refs() != from_ty {
diag.note(&format!("the contained type `{}` has an undefined layout", from_ty));
}
if !TyS::same_type(to_ty_orig.peel_refs(), to_ty) {
if to_ty_orig.peel_refs() != to_ty {
diag.note(&format!("the contained type `{}` has an undefined layout", to_ty));
}
}
@ -142,7 +140,7 @@ pub(super) fn check<'tcx>(
e.span,
&format!("transmute from `{}` which has an undefined layout", from_ty_orig),
|diag| {
if !TyS::same_type(from_ty_orig.peel_refs(), from_ty) {
if from_ty_orig.peel_refs() != from_ty {
diag.note(&format!("the contained type `{}` has an undefined layout", from_ty));
}
},
@ -159,7 +157,7 @@ pub(super) fn check<'tcx>(
e.span,
&format!("transmute into `{}` which has an undefined layout", to_ty_orig),
|diag| {
if !TyS::same_type(to_ty_orig.peel_refs(), to_ty) {
if to_ty_orig.peel_refs() != to_ty {
diag.note(&format!("the contained type `{}` has an undefined layout", to_ty));
}
},

View file

@ -54,9 +54,6 @@ impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector {
),
hir::VisibilityKind::Inherited => println!("visibility inherited from outer item"),
}
if item.defaultness.is_default() {
println!("default");
}
match item.kind {
hir::ImplItemKind::Const(_, body_id) => {
println!("associated constant");

View file

@ -612,8 +612,8 @@ fn get_lint_group_and_level_or_lint(
}
fn get_lint_group(cx: &LateContext<'_>, lint_id: LintId) -> Option<String> {
for (group_name, lints, _) in &cx.lint_store.get_lint_groups() {
if IGNORED_LINT_GROUPS.contains(group_name) {
for (group_name, lints, _) in cx.lint_store.get_lint_groups() {
if IGNORED_LINT_GROUPS.contains(&group_name) {
continue;
}

View file

@ -101,7 +101,7 @@ impl HirEqInterExpr<'_, '_, '_> {
if let Some(typeck) = self.inner.maybe_typeck_results {
let l_ty = typeck.pat_ty(l.pat);
let r_ty = typeck.pat_ty(r.pat);
if !rustc_middle::ty::TyS::same_type(l_ty, r_ty) {
if l_ty != r_ty {
return false;
}
}

View file

@ -340,15 +340,13 @@ impl<'tcx> FormatArgsExpn<'tcx> {
expr_visitor_no_bodies(|e| {
// if we're still inside of the macro definition...
if e.span.ctxt() == expr.span.ctxt() {
// ArgumnetV1::new(<value>, <format_trait>::fmt)
// ArgumnetV1::new_<format_trait>(<value>)
if_chain! {
if let ExprKind::Call(callee, [val, fmt_path]) = e.kind;
if let ExprKind::Call(callee, [val]) = e.kind;
if let ExprKind::Path(QPath::TypeRelative(ty, seg)) = callee.kind;
if seg.ident.name == sym::new;
if let hir::TyKind::Path(QPath::Resolved(_, path)) = ty.kind;
if path.segments.last().unwrap().ident.name == sym::ArgumentV1;
if let ExprKind::Path(QPath::Resolved(_, path)) = fmt_path.kind;
if let [.., fmt_trait, _fmt] = path.segments;
if seg.ident.name.as_str().starts_with("new_");
then {
let val_idx = if_chain! {
if val.span.ctxt() == expr.span.ctxt();
@ -362,7 +360,19 @@ impl<'tcx> FormatArgsExpn<'tcx> {
formatters.len()
}
};
formatters.push((val_idx, fmt_trait.ident.name));
let fmt_trait = match seg.ident.name.as_str() {
"new_display" => "Display",
"new_debug" => "Debug",
"new_lower_exp" => "LowerExp",
"new_upper_exp" => "UpperExp",
"new_octal" => "Octal",
"new_pointer" => "Pointer",
"new_binary" => "Binary",
"new_lower_hex" => "LowerHex",
"new_upper_hex" => "UpperHex",
_ => unreachable!(),
};
formatters.push((val_idx, Symbol::intern(fmt_trait)));
}
}
if let ExprKind::Struct(QPath::Resolved(_, path), ..) = e.kind {

View file

@ -32,6 +32,7 @@ pub fn is_min_const_fn<'a, 'tcx>(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv:
| ty::PredicateKind::Projection(_)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate),
ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {:#?}", predicate),

View file

@ -42,7 +42,7 @@ pub fn can_partially_move_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool
/// Walks into `ty` and returns `true` if any inner type is the same as `other_ty`
pub fn contains_ty(ty: Ty<'_>, other_ty: Ty<'_>) -> bool {
ty.walk().any(|inner| match inner.unpack() {
GenericArgKind::Type(inner_ty) => ty::TyS::same_type(other_ty, inner_ty),
GenericArgKind::Type(inner_ty) => other_ty == inner_ty,
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
})
}

View file

@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2022-01-27"
channel = "nightly-2022-02-10"
components = ["cargo", "llvm-tools-preview", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]

View file

@ -16,4 +16,27 @@ fn main() {
dbg!(42);
dbg!(dbg!(dbg!(42)));
foo(3) + dbg!(factorial(4));
dbg!(1, 2, dbg!(3, 4));
dbg!(1, 2, 3, 4, 5);
}
mod issue7274 {
trait Thing<'b> {
fn foo(&self);
}
macro_rules! define_thing {
($thing:ident, $body:expr) => {
impl<'a> Thing<'a> for $thing {
fn foo<'b>(&self) {
$body
}
}
};
}
struct MyThing;
define_thing!(MyThing, {
dbg!(2);
});
}

View file

@ -76,5 +76,38 @@ help: ensure to avoid having uses of it in version control
LL | foo(3) + factorial(4);
| ~~~~~~~~~~~~
error: aborting due to 7 previous errors
error: `dbg!` macro is intended as a debugging tool
--> $DIR/dbg_macro.rs:19:5
|
LL | dbg!(1, 2, dbg!(3, 4));
| ^^^^^^^^^^^^^^^^^^^^^^
|
help: ensure to avoid having uses of it in version control
|
LL | (1, 2, dbg!(3, 4));
| ~~~~~~~~~~~~~~~~~~
error: `dbg!` macro is intended as a debugging tool
--> $DIR/dbg_macro.rs:20:5
|
LL | dbg!(1, 2, 3, 4, 5);
| ^^^^^^^^^^^^^^^^^^^
|
help: ensure to avoid having uses of it in version control
|
LL | (1, 2, 3, 4, 5);
| ~~~~~~~~~~~~~~~
error: `dbg!` macro is intended as a debugging tool
--> $DIR/dbg_macro.rs:40:9
|
LL | dbg!(2);
| ^^^^^^^
|
help: ensure to avoid having uses of it in version control
|
LL | 2;
| ~
error: aborting due to 10 previous errors

View file

@ -1,4 +1,5 @@
#![warn(clippy::non_send_fields_in_send_ty)]
#![allow(suspicious_auto_trait_impls)]
#![feature(extern_types)]
use std::cell::UnsafeCell;

View file

@ -1,167 +1,167 @@
error: some fields in `RingBuffer<T>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:16:1
--> $DIR/non_send_fields_in_send_ty.rs:17:1
|
LL | unsafe impl<T> Send for RingBuffer<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings`
note: it is not safe to send field `data` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:11:5
--> $DIR/non_send_fields_in_send_ty.rs:12:5
|
LL | data: Vec<UnsafeCell<T>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^
= help: add bounds on type parameter `T` that satisfy `Vec<UnsafeCell<T>>: Send`
error: some fields in `MvccRwLock<T>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:24:1
--> $DIR/non_send_fields_in_send_ty.rs:25:1
|
LL | unsafe impl<T> Send for MvccRwLock<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `lock` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:21:5
--> $DIR/non_send_fields_in_send_ty.rs:22:5
|
LL | lock: Mutex<Box<T>>,
| ^^^^^^^^^^^^^^^^^^^
= help: add bounds on type parameter `T` that satisfy `Mutex<Box<T>>: Send`
error: some fields in `ArcGuard<RC, T>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:32:1
--> $DIR/non_send_fields_in_send_ty.rs:33:1
|
LL | unsafe impl<RC, T: Send> Send for ArcGuard<RC, T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `head` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:29:5
--> $DIR/non_send_fields_in_send_ty.rs:30:5
|
LL | head: Arc<RC>,
| ^^^^^^^^^^^^^
= help: add bounds on type parameter `RC` that satisfy `Arc<RC>: Send`
error: some fields in `DeviceHandle<T>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:48:1
--> $DIR/non_send_fields_in_send_ty.rs:49:1
|
LL | unsafe impl<T: UsbContext> Send for DeviceHandle<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `context` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:44:5
--> $DIR/non_send_fields_in_send_ty.rs:45:5
|
LL | context: T,
| ^^^^^^^^^^
= help: add `T: Send` bound in `Send` impl
error: some fields in `NoGeneric` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:55:1
--> $DIR/non_send_fields_in_send_ty.rs:56:1
|
LL | unsafe impl Send for NoGeneric {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `rc_is_not_send` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:52:5
--> $DIR/non_send_fields_in_send_ty.rs:53:5
|
LL | rc_is_not_send: Rc<String>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: use a thread-safe type that implements `Send`
error: some fields in `MultiField<T>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:63:1
--> $DIR/non_send_fields_in_send_ty.rs:64:1
|
LL | unsafe impl<T> Send for MultiField<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `field1` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:58:5
--> $DIR/non_send_fields_in_send_ty.rs:59:5
|
LL | field1: T,
| ^^^^^^^^^
= help: add `T: Send` bound in `Send` impl
note: it is not safe to send field `field2` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:59:5
--> $DIR/non_send_fields_in_send_ty.rs:60:5
|
LL | field2: T,
| ^^^^^^^^^
= help: add `T: Send` bound in `Send` impl
note: it is not safe to send field `field3` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:60:5
--> $DIR/non_send_fields_in_send_ty.rs:61:5
|
LL | field3: T,
| ^^^^^^^^^
= help: add `T: Send` bound in `Send` impl
error: some fields in `MyOption<T>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:70:1
--> $DIR/non_send_fields_in_send_ty.rs:71:1
|
LL | unsafe impl<T> Send for MyOption<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `0` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:66:12
--> $DIR/non_send_fields_in_send_ty.rs:67:12
|
LL | MySome(T),
| ^
= help: add `T: Send` bound in `Send` impl
error: some fields in `MultiParam<A, B>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:82:1
--> $DIR/non_send_fields_in_send_ty.rs:83:1
|
LL | unsafe impl<A, B> Send for MultiParam<A, B> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `vec` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:79:5
--> $DIR/non_send_fields_in_send_ty.rs:80:5
|
LL | vec: Vec<(A, B)>,
| ^^^^^^^^^^^^^^^^
= help: add bounds on type parameters `A, B` that satisfy `Vec<(A, B)>: Send`
error: some fields in `HeuristicTest` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:100:1
--> $DIR/non_send_fields_in_send_ty.rs:101:1
|
LL | unsafe impl Send for HeuristicTest {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `field4` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:95:5
--> $DIR/non_send_fields_in_send_ty.rs:96:5
|
LL | field4: (*const NonSend, Rc<u8>),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: use a thread-safe type that implements `Send`
error: some fields in `AttrTest3<T>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:119:1
--> $DIR/non_send_fields_in_send_ty.rs:120:1
|
LL | unsafe impl<T> Send for AttrTest3<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `0` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:114:11
--> $DIR/non_send_fields_in_send_ty.rs:115:11
|
LL | Enum2(T),
| ^
= help: add `T: Send` bound in `Send` impl
error: some fields in `Complex<P, u32>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:127:1
--> $DIR/non_send_fields_in_send_ty.rs:128:1
|
LL | unsafe impl<P> Send for Complex<P, u32> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `field1` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:123:5
--> $DIR/non_send_fields_in_send_ty.rs:124:5
|
LL | field1: A,
| ^^^^^^^^^
= help: add `P: Send` bound in `Send` impl
error: some fields in `Complex<Q, MutexGuard<'static, bool>>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:130:1
--> $DIR/non_send_fields_in_send_ty.rs:131:1
|
LL | unsafe impl<Q: Send> Send for Complex<Q, MutexGuard<'static, bool>> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `field2` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:124:5
--> $DIR/non_send_fields_in_send_ty.rs:125:5
|
LL | field2: B,
| ^^^^^^^^^