mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Auto merge of #10313 - flip1995:rustup, r=flip1995
Rustup r? `@ghost` changelog: none
This commit is contained in:
commit
a7fecd6911
@ -6,9 +6,10 @@ use if_chain::if_chain;
|
|||||||
use rustc_ast::ast::LitKind;
|
use rustc_ast::ast::LitKind;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
|
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
|
||||||
use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, UnOp};
|
use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, UnOp};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
|
||||||
@ -82,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for NonminimalBool {
|
|||||||
_: &'tcx FnDecl<'_>,
|
_: &'tcx FnDecl<'_>,
|
||||||
body: &'tcx Body<'_>,
|
body: &'tcx Body<'_>,
|
||||||
_: Span,
|
_: Span,
|
||||||
_: HirId,
|
_: LocalDefId,
|
||||||
) {
|
) {
|
||||||
NonminimalBoolVisitor { cx }.visit_body(body);
|
NonminimalBoolVisitor { cx }.visit_body(body);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
|
|||||||
&& let ExprKind::MethodCall(method_name, receiver, [], _) = cast_expr.peel_blocks().kind
|
&& let ExprKind::MethodCall(method_name, receiver, [], _) = cast_expr.peel_blocks().kind
|
||||||
&& method_name.ident.name == rustc_span::sym::as_ptr
|
&& method_name.ident.name == rustc_span::sym::as_ptr
|
||||||
&& let Some(as_ptr_did) = cx.typeck_results().type_dependent_def_id(cast_expr.peel_blocks().hir_id)
|
&& let Some(as_ptr_did) = cx.typeck_results().type_dependent_def_id(cast_expr.peel_blocks().hir_id)
|
||||||
&& let as_ptr_sig = cx.tcx.fn_sig(as_ptr_did)
|
&& let as_ptr_sig = cx.tcx.fn_sig(as_ptr_did).subst_identity()
|
||||||
&& let Some(first_param_ty) = as_ptr_sig.skip_binder().inputs().iter().next()
|
&& let Some(first_param_ty) = as_ptr_sig.skip_binder().inputs().iter().next()
|
||||||
&& let ty::Ref(_, _, Mutability::Not) = first_param_ty.kind()
|
&& let ty::Ref(_, _, Mutability::Not) = first_param_ty.kind()
|
||||||
&& let Some(recv) = snippet_opt(cx, receiver.span)
|
&& let Some(recv) = snippet_opt(cx, receiver.span)
|
||||||
|
@ -8,9 +8,10 @@ use clippy_utils::{get_async_fn_body, is_async_fn, LimitStack};
|
|||||||
use core::ops::ControlFlow;
|
use core::ops::ControlFlow;
|
||||||
use rustc_ast::ast::Attribute;
|
use rustc_ast::ast::Attribute;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId};
|
use rustc_hir::{Body, Expr, ExprKind, FnDecl};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
use rustc_span::{sym, BytePos};
|
use rustc_span::{sym, BytePos};
|
||||||
|
|
||||||
@ -140,9 +141,8 @@ impl<'tcx> LateLintPass<'tcx> for CognitiveComplexity {
|
|||||||
decl: &'tcx FnDecl<'_>,
|
decl: &'tcx FnDecl<'_>,
|
||||||
body: &'tcx Body<'_>,
|
body: &'tcx Body<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
hir_id: HirId,
|
def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
let def_id = cx.tcx.hir().local_def_id(hir_id);
|
|
||||||
if !cx.tcx.has_attr(def_id.to_def_id(), sym::test) {
|
if !cx.tcx.has_attr(def_id.to_def_id(), sym::test) {
|
||||||
let expr = if is_async_fn(kind) {
|
let expr = if is_async_fn(kind) {
|
||||||
match get_async_fn_body(cx.tcx, body) {
|
match get_async_fn_body(cx.tcx, body) {
|
||||||
|
@ -141,7 +141,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
|
|||||||
|
|
||||||
ExprKind::MethodCall(_, receiver, args, _) => {
|
ExprKind::MethodCall(_, receiver, args, _) => {
|
||||||
if let Some(def_id) = self.cx.typeck_results().type_dependent_def_id(expr.hir_id) {
|
if let Some(def_id) = self.cx.typeck_results().type_dependent_def_id(expr.hir_id) {
|
||||||
let fn_sig = self.cx.tcx.fn_sig(def_id).skip_binder();
|
let fn_sig = self.cx.tcx.fn_sig(def_id).subst_identity().skip_binder();
|
||||||
for (expr, bound) in iter::zip(std::iter::once(*receiver).chain(args.iter()), fn_sig.inputs()) {
|
for (expr, bound) in iter::zip(std::iter::once(*receiver).chain(args.iter()), fn_sig.inputs()) {
|
||||||
self.ty_bounds.push((*bound).into());
|
self.ty_bounds.push((*bound).into());
|
||||||
self.visit_expr(expr);
|
self.visit_expr(expr);
|
||||||
@ -215,7 +215,7 @@ fn fn_sig_opt<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<PolyFnSig<'
|
|||||||
let node_ty = cx.typeck_results().node_type_opt(hir_id)?;
|
let node_ty = cx.typeck_results().node_type_opt(hir_id)?;
|
||||||
// We can't use `Ty::fn_sig` because it automatically performs substs, this may result in FNs.
|
// We can't use `Ty::fn_sig` because it automatically performs substs, this may result in FNs.
|
||||||
match node_ty.kind() {
|
match node_ty.kind() {
|
||||||
ty::FnDef(def_id, _) => Some(cx.tcx.fn_sig(*def_id)),
|
ty::FnDef(def_id, _) => Some(cx.tcx.fn_sig(*def_id).subst_identity()),
|
||||||
ty::FnPtr(fn_sig) => Some(*fn_sig),
|
ty::FnPtr(fn_sig) => Some(*fn_sig),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -759,7 +759,7 @@ fn walk_parents<'tcx>(
|
|||||||
}) if span.ctxt() == ctxt => {
|
}) if span.ctxt() == ctxt => {
|
||||||
let output = cx
|
let output = cx
|
||||||
.tcx
|
.tcx
|
||||||
.erase_late_bound_regions(cx.tcx.fn_sig(owner_id.to_def_id()).output());
|
.erase_late_bound_regions(cx.tcx.fn_sig(owner_id).subst_identity().output());
|
||||||
Some(ty_auto_deref_stability(cx, output, precedence).position_for_result(cx))
|
Some(ty_auto_deref_stability(cx, output, precedence).position_for_result(cx))
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -778,20 +778,20 @@ fn walk_parents<'tcx>(
|
|||||||
|
|
||||||
Node::Expr(parent) if parent.span.ctxt() == ctxt => match parent.kind {
|
Node::Expr(parent) if parent.span.ctxt() == ctxt => match parent.kind {
|
||||||
ExprKind::Ret(_) => {
|
ExprKind::Ret(_) => {
|
||||||
let owner_id = cx.tcx.hir().body_owner(cx.enclosing_body.unwrap());
|
let owner_id = cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap());
|
||||||
Some(
|
Some(
|
||||||
if let Node::Expr(
|
if let Node::Expr(
|
||||||
closure_expr @ Expr {
|
closure_expr @ Expr {
|
||||||
kind: ExprKind::Closure(closure),
|
kind: ExprKind::Closure(closure),
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
) = cx.tcx.hir().get(owner_id)
|
) = cx.tcx.hir().get_by_def_id(owner_id)
|
||||||
{
|
{
|
||||||
closure_result_position(cx, closure, cx.typeck_results().expr_ty(closure_expr), precedence)
|
closure_result_position(cx, closure, cx.typeck_results().expr_ty(closure_expr), precedence)
|
||||||
} else {
|
} else {
|
||||||
let output = cx
|
let output = cx
|
||||||
.tcx
|
.tcx
|
||||||
.erase_late_bound_regions(cx.tcx.fn_sig(cx.tcx.hir().local_def_id(owner_id)).output());
|
.erase_late_bound_regions(cx.tcx.fn_sig(owner_id).subst_identity().output());
|
||||||
ty_auto_deref_stability(cx, output, precedence).position_for_result(cx)
|
ty_auto_deref_stability(cx, output, precedence).position_for_result(cx)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -858,7 +858,7 @@ fn walk_parents<'tcx>(
|
|||||||
&& let subs = cx
|
&& let subs = cx
|
||||||
.typeck_results()
|
.typeck_results()
|
||||||
.node_substs_opt(parent.hir_id).map(|subs| &subs[1..]).unwrap_or_default()
|
.node_substs_opt(parent.hir_id).map(|subs| &subs[1..]).unwrap_or_default()
|
||||||
&& let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
|
&& let impl_ty = if cx.tcx.fn_sig(id).subst_identity().skip_binder().inputs()[0].is_ref() {
|
||||||
// Trait methods taking `&self`
|
// Trait methods taking `&self`
|
||||||
sub_ty
|
sub_ty
|
||||||
} else {
|
} else {
|
||||||
@ -879,7 +879,7 @@ fn walk_parents<'tcx>(
|
|||||||
return Some(Position::MethodReceiver);
|
return Some(Position::MethodReceiver);
|
||||||
}
|
}
|
||||||
args.iter().position(|arg| arg.hir_id == child_id).map(|i| {
|
args.iter().position(|arg| arg.hir_id == child_id).map(|i| {
|
||||||
let ty = cx.tcx.fn_sig(id).skip_binder().inputs()[i + 1];
|
let ty = cx.tcx.fn_sig(id).subst_identity().skip_binder().inputs()[i + 1];
|
||||||
// `e.hir_id == child_id` for https://github.com/rust-lang/rust-clippy/issues/9739
|
// `e.hir_id == child_id` for https://github.com/rust-lang/rust-clippy/issues/9739
|
||||||
// `method.args.is_none()` for https://github.com/rust-lang/rust-clippy/issues/9782
|
// `method.args.is_none()` for https://github.com/rust-lang/rust-clippy/issues/9782
|
||||||
if e.hir_id == child_id && method.args.is_none() && let ty::Param(param_ty) = ty.kind() {
|
if e.hir_id == child_id && method.args.is_none() && let ty::Param(param_ty) = ty.kind() {
|
||||||
@ -896,7 +896,7 @@ fn walk_parents<'tcx>(
|
|||||||
} else {
|
} else {
|
||||||
ty_auto_deref_stability(
|
ty_auto_deref_stability(
|
||||||
cx,
|
cx,
|
||||||
cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).input(i + 1)),
|
cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).subst_identity().input(i + 1)),
|
||||||
precedence,
|
precedence,
|
||||||
)
|
)
|
||||||
.position_for_arg()
|
.position_for_arg()
|
||||||
@ -1093,7 +1093,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
|
|||||||
let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
|
let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
|
||||||
|
|
||||||
let Some(callee_def_id) = fn_def_id(cx, parent) else { return Position::Other(precedence) };
|
let Some(callee_def_id) = fn_def_id(cx, parent) else { return Position::Other(precedence) };
|
||||||
let fn_sig = cx.tcx.fn_sig(callee_def_id).skip_binder();
|
let fn_sig = cx.tcx.fn_sig(callee_def_id).subst_identity().skip_binder();
|
||||||
let substs_with_expr_ty = cx
|
let substs_with_expr_ty = cx
|
||||||
.typeck_results()
|
.typeck_results()
|
||||||
.node_substs(if let ExprKind::Call(callee, _) = parent.kind {
|
.node_substs(if let ExprKind::Call(callee, _) = parent.kind {
|
||||||
@ -1221,7 +1221,7 @@ fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
|
|||||||
.in_definition_order()
|
.in_definition_order()
|
||||||
.any(|assoc_item| {
|
.any(|assoc_item| {
|
||||||
if assoc_item.fn_has_self_parameter {
|
if assoc_item.fn_has_self_parameter {
|
||||||
let self_ty = cx.tcx.fn_sig(assoc_item.def_id).skip_binder().inputs()[0];
|
let self_ty = cx.tcx.fn_sig(assoc_item.def_id).subst_identity().skip_binder().inputs()[0];
|
||||||
matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Mut))
|
matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Mut))
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@ -1419,6 +1419,7 @@ fn ty_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, precedenc
|
|||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::Generator(..)
|
| ty::Generator(..)
|
||||||
| ty::GeneratorWitness(..)
|
| ty::GeneratorWitness(..)
|
||||||
|
| ty::GeneratorWitnessMIR(..)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::Tuple(_)
|
| ty::Tuple(_)
|
||||||
|
@ -7,7 +7,7 @@ use rustc_errors::Applicability;
|
|||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor};
|
use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor};
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
self as hir, BlockCheckMode, BodyId, Constness, Expr, ExprKind, FnDecl, HirId, Impl, Item, ItemKind, UnsafeSource,
|
self as hir, BlockCheckMode, BodyId, Constness, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, UnsafeSource,
|
||||||
Unsafety,
|
Unsafety,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
@ -18,6 +18,7 @@ use rustc_middle::ty::{
|
|||||||
TraitPredicate, Ty, TyCtxt,
|
TraitPredicate, Ty, TyCtxt,
|
||||||
};
|
};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
|
||||||
@ -425,7 +426,7 @@ struct UnsafeVisitor<'a, 'tcx> {
|
|||||||
impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
|
impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
|
||||||
type NestedFilter = nested_filter::All;
|
type NestedFilter = nested_filter::All;
|
||||||
|
|
||||||
fn visit_fn(&mut self, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body_id: BodyId, _: Span, id: HirId) {
|
fn visit_fn(&mut self, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body_id: BodyId, _: Span, id: LocalDefId) {
|
||||||
if self.has_unsafe {
|
if self.has_unsafe {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ use rustc_parse::maybe_new_parser_from_source_str;
|
|||||||
use rustc_parse::parser::ForceCollect;
|
use rustc_parse::parser::ForceCollect;
|
||||||
use rustc_session::parse::ParseSess;
|
use rustc_session::parse::ParseSess;
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
use rustc_span::def_id::LocalDefId;
|
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
use rustc_span::source_map::{BytePos, FilePathMapping, SourceMap, Span};
|
use rustc_span::source_map::{BytePos, FilePathMapping, SourceMap, Span};
|
||||||
use rustc_span::{sym, FileName, Pos};
|
use rustc_span::{sym, FileName, Pos};
|
||||||
@ -302,7 +301,7 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
|
|||||||
panic_span: None,
|
panic_span: None,
|
||||||
};
|
};
|
||||||
fpu.visit_expr(body.value);
|
fpu.visit_expr(body.value);
|
||||||
lint_for_missing_headers(cx, item.owner_id.def_id, sig, headers, Some(body_id), fpu.panic_span);
|
lint_for_missing_headers(cx, item.owner_id, sig, headers, Some(body_id), fpu.panic_span);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hir::ItemKind::Impl(impl_) => {
|
hir::ItemKind::Impl(impl_) => {
|
||||||
@ -338,7 +337,7 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
|
|||||||
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
|
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
|
||||||
if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
|
if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
|
||||||
if !in_external_macro(cx.tcx.sess, item.span) {
|
if !in_external_macro(cx.tcx.sess, item.span) {
|
||||||
lint_for_missing_headers(cx, item.owner_id.def_id, sig, headers, None, None);
|
lint_for_missing_headers(cx, item.owner_id, sig, headers, None, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -357,20 +356,20 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
|
|||||||
panic_span: None,
|
panic_span: None,
|
||||||
};
|
};
|
||||||
fpu.visit_expr(body.value);
|
fpu.visit_expr(body.value);
|
||||||
lint_for_missing_headers(cx, item.owner_id.def_id, sig, headers, Some(body_id), fpu.panic_span);
|
lint_for_missing_headers(cx, item.owner_id, sig, headers, Some(body_id), fpu.panic_span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lint_for_missing_headers(
|
fn lint_for_missing_headers(
|
||||||
cx: &LateContext<'_>,
|
cx: &LateContext<'_>,
|
||||||
def_id: LocalDefId,
|
owner_id: hir::OwnerId,
|
||||||
sig: &hir::FnSig<'_>,
|
sig: &hir::FnSig<'_>,
|
||||||
headers: DocHeaders,
|
headers: DocHeaders,
|
||||||
body_id: Option<hir::BodyId>,
|
body_id: Option<hir::BodyId>,
|
||||||
panic_span: Option<Span>,
|
panic_span: Option<Span>,
|
||||||
) {
|
) {
|
||||||
if !cx.effective_visibilities.is_exported(def_id) {
|
if !cx.effective_visibilities.is_exported(owner_id.def_id) {
|
||||||
return; // Private functions do not require doc comments
|
return; // Private functions do not require doc comments
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,13 +377,13 @@ fn lint_for_missing_headers(
|
|||||||
if cx
|
if cx
|
||||||
.tcx
|
.tcx
|
||||||
.hir()
|
.hir()
|
||||||
.parent_iter(cx.tcx.hir().local_def_id_to_hir_id(def_id))
|
.parent_iter(owner_id.into())
|
||||||
.any(|(id, _node)| is_doc_hidden(cx.tcx.hir().attrs(id)))
|
.any(|(id, _node)| is_doc_hidden(cx.tcx.hir().attrs(id)))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let span = cx.tcx.def_span(def_id);
|
let span = cx.tcx.def_span(owner_id);
|
||||||
match (headers.safety, sig.header.unsafety) {
|
match (headers.safety, sig.header.unsafety) {
|
||||||
(false, hir::Unsafety::Unsafe) => span_lint(
|
(false, hir::Unsafety::Unsafe) => span_lint(
|
||||||
cx,
|
cx,
|
||||||
@ -411,8 +410,7 @@ fn lint_for_missing_headers(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if !headers.errors {
|
if !headers.errors {
|
||||||
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
|
if is_type_diagnostic_item(cx, return_ty(cx, owner_id), sym::Result) {
|
||||||
if is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::Result) {
|
|
||||||
span_lint(
|
span_lint(
|
||||||
cx,
|
cx,
|
||||||
MISSING_ERRORS_DOC,
|
MISSING_ERRORS_DOC,
|
||||||
|
@ -8,6 +8,7 @@ use rustc_middle::mir::FakeReadCause;
|
|||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
use rustc_middle::ty::{self, TraitRef, Ty};
|
use rustc_middle::ty::{self, TraitRef, Ty};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
use rustc_span::symbol::kw;
|
use rustc_span::symbol::kw;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
@ -63,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
|
|||||||
_: &'tcx FnDecl<'_>,
|
_: &'tcx FnDecl<'_>,
|
||||||
body: &'tcx Body<'_>,
|
body: &'tcx Body<'_>,
|
||||||
_: Span,
|
_: Span,
|
||||||
hir_id: HirId,
|
fn_def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
if let Some(header) = fn_kind.header() {
|
if let Some(header) = fn_kind.header() {
|
||||||
if header.abi != Abi::Rust {
|
if header.abi != Abi::Rust {
|
||||||
@ -71,7 +72,11 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let parent_id = cx.tcx.hir().get_parent_item(hir_id).def_id;
|
let parent_id = cx
|
||||||
|
.tcx
|
||||||
|
.hir()
|
||||||
|
.get_parent_item(cx.tcx.hir().local_def_id_to_hir_id(fn_def_id))
|
||||||
|
.def_id;
|
||||||
let parent_node = cx.tcx.hir().find_by_def_id(parent_id);
|
let parent_node = cx.tcx.hir().find_by_def_id(parent_id);
|
||||||
|
|
||||||
let mut trait_self_ty = None;
|
let mut trait_self_ty = None;
|
||||||
@ -84,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
|
|||||||
// find `self` ty for this trait if relevant
|
// find `self` ty for this trait if relevant
|
||||||
if let ItemKind::Trait(_, _, _, _, items) = item.kind {
|
if let ItemKind::Trait(_, _, _, _, items) = item.kind {
|
||||||
for trait_item in items {
|
for trait_item in items {
|
||||||
if trait_item.id.hir_id() == hir_id {
|
if trait_item.id.owner_id.def_id == fn_def_id {
|
||||||
// be sure we have `self` parameter in this function
|
// be sure we have `self` parameter in this function
|
||||||
if trait_item.kind == (AssocItemKind::Fn { has_self: true }) {
|
if trait_item.kind == (AssocItemKind::Fn { has_self: true }) {
|
||||||
trait_self_ty = Some(
|
trait_self_ty = Some(
|
||||||
@ -105,7 +110,6 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
|
|||||||
too_large_for_stack: self.too_large_for_stack,
|
too_large_for_stack: self.too_large_for_stack,
|
||||||
};
|
};
|
||||||
|
|
||||||
let fn_def_id = cx.tcx.hir().local_def_id(hir_id);
|
|
||||||
let infcx = cx.tcx.infer_ctxt().build();
|
let infcx = cx.tcx.infer_ctxt().build();
|
||||||
ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
|
ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_help;
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
use clippy_utils::{get_parent_as_impl, has_repr_attr, is_bool};
|
use clippy_utils::{get_parent_as_impl, has_repr_attr, is_bool};
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{Body, FnDecl, HirId, Item, ItemKind, TraitFn, TraitItem, TraitItemKind, Ty};
|
use rustc_hir::{Body, FnDecl, Item, ItemKind, TraitFn, TraitItem, TraitItemKind, Ty};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
@ -168,8 +169,9 @@ impl<'tcx> LateLintPass<'tcx> for ExcessiveBools {
|
|||||||
fn_decl: &'tcx FnDecl<'tcx>,
|
fn_decl: &'tcx FnDecl<'tcx>,
|
||||||
_: &'tcx Body<'tcx>,
|
_: &'tcx Body<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
hir_id: HirId,
|
def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
|
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
if let Some(fn_header) = fn_kind.header()
|
if let Some(fn_header) = fn_kind.header()
|
||||||
&& fn_header.abi == Abi::Rust
|
&& fn_header.abi == Abi::Rust
|
||||||
&& get_parent_as_impl(cx.tcx, hir_id)
|
&& get_parent_as_impl(cx.tcx, hir_id)
|
||||||
|
@ -79,8 +79,7 @@ impl LateLintPass<'_> for ExhaustiveItems {
|
|||||||
then {
|
then {
|
||||||
let (lint, msg) = if let ItemKind::Struct(ref v, ..) = item.kind {
|
let (lint, msg) = if let ItemKind::Struct(ref v, ..) = item.kind {
|
||||||
if v.fields().iter().any(|f| {
|
if v.fields().iter().any(|f| {
|
||||||
let def_id = cx.tcx.hir().local_def_id(f.hir_id);
|
!cx.tcx.visibility(f.def_id).is_public()
|
||||||
!cx.tcx.visibility(def_id).is_public()
|
|
||||||
}) {
|
}) {
|
||||||
// skip structs with private fields
|
// skip structs with private fields
|
||||||
return;
|
return;
|
||||||
|
@ -311,6 +311,10 @@ fn check_uninlined_args(
|
|||||||
// in those cases, make the code suggestion hidden
|
// in those cases, make the code suggestion hidden
|
||||||
let multiline_fix = fixes.iter().any(|(span, _)| cx.sess().source_map().is_multiline(*span));
|
let multiline_fix = fixes.iter().any(|(span, _)| cx.sess().source_map().is_multiline(*span));
|
||||||
|
|
||||||
|
// Suggest removing each argument only once, for example in `format!("{0} {0}", arg)`.
|
||||||
|
fixes.sort_unstable_by_key(|(span, _)| *span);
|
||||||
|
fixes.dedup_by_key(|(span, _)| *span);
|
||||||
|
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
UNINLINED_FORMAT_ARGS,
|
UNINLINED_FORMAT_ARGS,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::source::snippet;
|
use clippy_utils::source::snippet;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{intravisit::FnKind, Body, ExprKind, FnDecl, HirId, ImplicitSelfKind, Unsafety};
|
use rustc_hir::{intravisit::FnKind, Body, ExprKind, FnDecl, ImplicitSelfKind, Unsafety};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
@ -10,14 +10,7 @@ use std::iter;
|
|||||||
|
|
||||||
use super::MISNAMED_GETTERS;
|
use super::MISNAMED_GETTERS;
|
||||||
|
|
||||||
pub fn check_fn(
|
pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body: &Body<'_>, span: Span) {
|
||||||
cx: &LateContext<'_>,
|
|
||||||
kind: FnKind<'_>,
|
|
||||||
decl: &FnDecl<'_>,
|
|
||||||
body: &Body<'_>,
|
|
||||||
span: Span,
|
|
||||||
_hir_id: HirId,
|
|
||||||
) {
|
|
||||||
let FnKind::Method(ref ident, sig) = kind else {
|
let FnKind::Method(ref ident, sig) = kind else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -9,6 +9,7 @@ use rustc_hir as hir;
|
|||||||
use rustc_hir::intravisit;
|
use rustc_hir::intravisit;
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
@ -363,12 +364,13 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
|
|||||||
decl: &'tcx hir::FnDecl<'_>,
|
decl: &'tcx hir::FnDecl<'_>,
|
||||||
body: &'tcx hir::Body<'_>,
|
body: &'tcx hir::Body<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
hir_id: hir::HirId,
|
def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
|
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
too_many_arguments::check_fn(cx, kind, decl, span, hir_id, self.too_many_arguments_threshold);
|
too_many_arguments::check_fn(cx, kind, decl, span, hir_id, self.too_many_arguments_threshold);
|
||||||
too_many_lines::check_fn(cx, kind, span, body, self.too_many_lines_threshold);
|
too_many_lines::check_fn(cx, kind, span, body, self.too_many_lines_threshold);
|
||||||
not_unsafe_ptr_arg_deref::check_fn(cx, kind, decl, body, hir_id);
|
not_unsafe_ptr_arg_deref::check_fn(cx, kind, decl, body, def_id);
|
||||||
misnamed_getters::check_fn(cx, kind, decl, body, span, hir_id);
|
misnamed_getters::check_fn(cx, kind, decl, body, span);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
|
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use rustc_ast::ast::Attribute;
|
use rustc_ast::ast::Attribute;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::def_id::{DefIdSet, LocalDefId};
|
use rustc_hir::def_id::DefIdSet;
|
||||||
use rustc_hir::{self as hir, def::Res, QPath};
|
use rustc_hir::{self as hir, def::Res, QPath};
|
||||||
use rustc_lint::{LateContext, LintContext};
|
use rustc_lint::{LateContext, LintContext};
|
||||||
use rustc_middle::{
|
use rustc_middle::{
|
||||||
@ -27,14 +27,14 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
|
|||||||
let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
|
let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
|
||||||
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
|
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
|
||||||
if let Some(attr) = attr {
|
if let Some(attr) = attr {
|
||||||
check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr);
|
check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr);
|
||||||
} else if is_public && !is_proc_macro(cx.sess(), attrs) && !attrs.iter().any(|a| a.has_name(sym::no_mangle)) {
|
} else if is_public && !is_proc_macro(cx.sess(), attrs) && !attrs.iter().any(|a| a.has_name(sym::no_mangle)) {
|
||||||
check_must_use_candidate(
|
check_must_use_candidate(
|
||||||
cx,
|
cx,
|
||||||
sig.decl,
|
sig.decl,
|
||||||
cx.tcx.hir().body(*body_id),
|
cx.tcx.hir().body(*body_id),
|
||||||
item.span,
|
item.span,
|
||||||
item.owner_id.def_id,
|
item.owner_id,
|
||||||
item.span.with_hi(sig.decl.output.span().hi()),
|
item.span.with_hi(sig.decl.output.span().hi()),
|
||||||
"this function could have a `#[must_use]` attribute",
|
"this function could have a `#[must_use]` attribute",
|
||||||
);
|
);
|
||||||
@ -49,7 +49,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
|
|||||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||||
let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use);
|
let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use);
|
||||||
if let Some(attr) = attr {
|
if let Some(attr) = attr {
|
||||||
check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr);
|
check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr);
|
||||||
} else if is_public
|
} else if is_public
|
||||||
&& !is_proc_macro(cx.sess(), attrs)
|
&& !is_proc_macro(cx.sess(), attrs)
|
||||||
&& trait_ref_of_method(cx, item.owner_id.def_id).is_none()
|
&& trait_ref_of_method(cx, item.owner_id.def_id).is_none()
|
||||||
@ -59,7 +59,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
|
|||||||
sig.decl,
|
sig.decl,
|
||||||
cx.tcx.hir().body(*body_id),
|
cx.tcx.hir().body(*body_id),
|
||||||
item.span,
|
item.span,
|
||||||
item.owner_id.def_id,
|
item.owner_id,
|
||||||
item.span.with_hi(sig.decl.output.span().hi()),
|
item.span.with_hi(sig.decl.output.span().hi()),
|
||||||
"this method could have a `#[must_use]` attribute",
|
"this method could have a `#[must_use]` attribute",
|
||||||
);
|
);
|
||||||
@ -75,7 +75,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr
|
|||||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||||
let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use);
|
let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use);
|
||||||
if let Some(attr) = attr {
|
if let Some(attr) = attr {
|
||||||
check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr);
|
check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr);
|
||||||
} else if let hir::TraitFn::Provided(eid) = *eid {
|
} else if let hir::TraitFn::Provided(eid) = *eid {
|
||||||
let body = cx.tcx.hir().body(eid);
|
let body = cx.tcx.hir().body(eid);
|
||||||
if attr.is_none() && is_public && !is_proc_macro(cx.sess(), attrs) {
|
if attr.is_none() && is_public && !is_proc_macro(cx.sess(), attrs) {
|
||||||
@ -84,7 +84,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr
|
|||||||
sig.decl,
|
sig.decl,
|
||||||
body,
|
body,
|
||||||
item.span,
|
item.span,
|
||||||
item.owner_id.def_id,
|
item.owner_id,
|
||||||
item.span.with_hi(sig.decl.output.span().hi()),
|
item.span.with_hi(sig.decl.output.span().hi()),
|
||||||
"this method could have a `#[must_use]` attribute",
|
"this method could have a `#[must_use]` attribute",
|
||||||
);
|
);
|
||||||
@ -96,7 +96,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr
|
|||||||
fn check_needless_must_use(
|
fn check_needless_must_use(
|
||||||
cx: &LateContext<'_>,
|
cx: &LateContext<'_>,
|
||||||
decl: &hir::FnDecl<'_>,
|
decl: &hir::FnDecl<'_>,
|
||||||
item_id: hir::HirId,
|
item_id: hir::OwnerId,
|
||||||
item_span: Span,
|
item_span: Span,
|
||||||
fn_header_span: Span,
|
fn_header_span: Span,
|
||||||
attr: &Attribute,
|
attr: &Attribute,
|
||||||
@ -131,7 +131,7 @@ fn check_must_use_candidate<'tcx>(
|
|||||||
decl: &'tcx hir::FnDecl<'_>,
|
decl: &'tcx hir::FnDecl<'_>,
|
||||||
body: &'tcx hir::Body<'_>,
|
body: &'tcx hir::Body<'_>,
|
||||||
item_span: Span,
|
item_span: Span,
|
||||||
item_id: LocalDefId,
|
item_id: hir::OwnerId,
|
||||||
fn_span: Span,
|
fn_span: Span,
|
||||||
msg: &str,
|
msg: &str,
|
||||||
) {
|
) {
|
||||||
@ -139,8 +139,8 @@ fn check_must_use_candidate<'tcx>(
|
|||||||
|| mutates_static(cx, body)
|
|| mutates_static(cx, body)
|
||||||
|| in_external_macro(cx.sess(), item_span)
|
|| in_external_macro(cx.sess(), item_span)
|
||||||
|| returns_unit(decl)
|
|| returns_unit(decl)
|
||||||
|| !cx.effective_visibilities.is_exported(item_id)
|
|| !cx.effective_visibilities.is_exported(item_id.def_id)
|
||||||
|| is_must_use_ty(cx, return_ty(cx, cx.tcx.hir().local_def_id_to_hir_id(item_id)))
|
|| is_must_use_ty(cx, return_ty(cx, item_id))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ pub(super) fn check_fn<'tcx>(
|
|||||||
kind: intravisit::FnKind<'tcx>,
|
kind: intravisit::FnKind<'tcx>,
|
||||||
decl: &'tcx hir::FnDecl<'tcx>,
|
decl: &'tcx hir::FnDecl<'tcx>,
|
||||||
body: &'tcx hir::Body<'tcx>,
|
body: &'tcx hir::Body<'tcx>,
|
||||||
hir_id: hir::HirId,
|
def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
let unsafety = match kind {
|
let unsafety = match kind {
|
||||||
intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }) => unsafety,
|
intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }) => unsafety,
|
||||||
@ -25,7 +25,7 @@ pub(super) fn check_fn<'tcx>(
|
|||||||
intravisit::FnKind::Closure => return,
|
intravisit::FnKind::Closure => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
check_raw_ptr(cx, unsafety, decl, body, cx.tcx.hir().local_def_id(hir_id));
|
check_raw_ptr(cx, unsafety, decl, body, def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
|
pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
|
||||||
@ -58,7 +58,7 @@ fn check_raw_ptr<'tcx>(
|
|||||||
},
|
},
|
||||||
hir::ExprKind::MethodCall(_, recv, args, _) => {
|
hir::ExprKind::MethodCall(_, recv, args, _) => {
|
||||||
let def_id = typeck.type_dependent_def_id(e.hir_id).unwrap();
|
let def_id = typeck.type_dependent_def_id(e.hir_id).unwrap();
|
||||||
if cx.tcx.fn_sig(def_id).skip_binder().unsafety == hir::Unsafety::Unsafe {
|
if cx.tcx.fn_sig(def_id).skip_binder().skip_binder().unsafety == hir::Unsafety::Unsafe {
|
||||||
check_arg(cx, &raw_ptrs, recv);
|
check_arg(cx, &raw_ptrs, recv);
|
||||||
for arg in args {
|
for arg in args {
|
||||||
check_arg(cx, &raw_ptrs, arg);
|
check_arg(cx, &raw_ptrs, arg);
|
||||||
|
@ -21,7 +21,7 @@ fn result_err_ty<'tcx>(
|
|||||||
) -> Option<(&'tcx hir::Ty<'tcx>, Ty<'tcx>)> {
|
) -> Option<(&'tcx hir::Ty<'tcx>, Ty<'tcx>)> {
|
||||||
if !in_external_macro(cx.sess(), item_span)
|
if !in_external_macro(cx.sess(), item_span)
|
||||||
&& let hir::FnRetTy::Return(hir_ty) = decl.output
|
&& let hir::FnRetTy::Return(hir_ty) = decl.output
|
||||||
&& let ty = cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).output())
|
&& let ty = cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).subst_identity().output())
|
||||||
&& is_type_diagnostic_item(cx, ty, sym::Result)
|
&& is_type_diagnostic_item(cx, ty, sym::Result)
|
||||||
&& let ty::Adt(_, substs) = ty.kind()
|
&& let ty::Adt(_, substs) = ty.kind()
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::return_ty;
|
use clippy_utils::return_ty;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{Body, FnDecl, HirId};
|
use rustc_hir::{Body, FnDecl};
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::ty::{self, AliasTy, Clause, EarlyBinder, PredicateKind};
|
use rustc_middle::ty::{self, AliasTy, Clause, EarlyBinder, PredicateKind};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::{sym, Span};
|
use rustc_span::{sym, Span};
|
||||||
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt;
|
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt;
|
||||||
use rustc_trait_selection::traits::{self, FulfillmentError};
|
use rustc_trait_selection::traits::{self, FulfillmentError};
|
||||||
@ -56,12 +57,12 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
|
|||||||
decl: &'tcx FnDecl<'tcx>,
|
decl: &'tcx FnDecl<'tcx>,
|
||||||
_: &'tcx Body<'tcx>,
|
_: &'tcx Body<'tcx>,
|
||||||
_: Span,
|
_: Span,
|
||||||
hir_id: HirId,
|
fn_def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
if let FnKind::Closure = kind {
|
if let FnKind::Closure = kind {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let ret_ty = return_ty(cx, hir_id);
|
let ret_ty = return_ty(cx, cx.tcx.hir().local_def_id_to_hir_id(fn_def_id).expect_owner());
|
||||||
if let ty::Alias(ty::Opaque, AliasTy { def_id, substs, .. }) = *ret_ty.kind() {
|
if let ty::Alias(ty::Opaque, AliasTy { def_id, substs, .. }) = *ret_ty.kind() {
|
||||||
let preds = cx.tcx.explicit_item_bounds(def_id);
|
let preds = cx.tcx.explicit_item_bounds(def_id);
|
||||||
let mut is_future = false;
|
let mut is_future = false;
|
||||||
@ -78,8 +79,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
|
|||||||
let send_trait = cx.tcx.get_diagnostic_item(sym::Send).unwrap();
|
let send_trait = cx.tcx.get_diagnostic_item(sym::Send).unwrap();
|
||||||
let span = decl.output.span();
|
let span = decl.output.span();
|
||||||
let infcx = cx.tcx.infer_ctxt().build();
|
let infcx = cx.tcx.infer_ctxt().build();
|
||||||
let def_id = cx.tcx.hir().local_def_id(hir_id);
|
let cause = traits::ObligationCause::misc(span, fn_def_id);
|
||||||
let cause = traits::ObligationCause::misc(span, def_id);
|
|
||||||
let send_errors = traits::fully_solve_bound(&infcx, cause, cx.param_env, ret_ty, send_trait);
|
let send_errors = traits::fully_solve_bound(&infcx, cause, cx.param_env, ret_ty, send_trait);
|
||||||
if !send_errors.is_empty() {
|
if !send_errors.is_empty() {
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
|
@ -11,6 +11,7 @@ use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, FnRetTy, HirId};
|
|||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::{Span, SyntaxContext};
|
use rustc_span::{Span, SyntaxContext};
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
@ -223,7 +224,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitReturn {
|
|||||||
decl: &'tcx FnDecl<'_>,
|
decl: &'tcx FnDecl<'_>,
|
||||||
body: &'tcx Body<'_>,
|
body: &'tcx Body<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
_: HirId,
|
_: LocalDefId,
|
||||||
) {
|
) {
|
||||||
if (!matches!(kind, FnKind::Closure) && matches!(decl.output, FnRetTy::DefaultReturn(_)))
|
if (!matches!(kind, FnKind::Closure) && matches!(decl.output, FnRetTy::DefaultReturn(_)))
|
||||||
|| span.ctxt() != body.value.span.ctxt()
|
|| span.ctxt() != body.value.span.ctxt()
|
||||||
|
@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
|
|||||||
if impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }));
|
if impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }));
|
||||||
|
|
||||||
// Check if return type is String
|
// Check if return type is String
|
||||||
if is_type_lang_item(cx, return_ty(cx, impl_item.hir_id()), LangItem::String);
|
if is_type_lang_item(cx, return_ty(cx, impl_item.owner_id), LangItem::String);
|
||||||
|
|
||||||
// Filters instances of to_string which are required by a trait
|
// Filters instances of to_string which are required by a trait
|
||||||
if trait_ref_of_method(cx, impl_item.owner_id.def_id).is_none();
|
if trait_ref_of_method(cx, impl_item.owner_id.def_id).is_none();
|
||||||
@ -124,7 +124,7 @@ fn show_lint(cx: &LateContext<'_>, item: &ImplItem<'_>) {
|
|||||||
.expect("Failed to get trait ID of `Display`!");
|
.expect("Failed to get trait ID of `Display`!");
|
||||||
|
|
||||||
// Get the real type of 'self'
|
// Get the real type of 'self'
|
||||||
let self_type = cx.tcx.fn_sig(item.owner_id).input(0);
|
let self_type = cx.tcx.fn_sig(item.owner_id).skip_binder().input(0);
|
||||||
let self_type = self_type.skip_binder().peel_refs();
|
let self_type = self_type.skip_binder().peel_refs();
|
||||||
|
|
||||||
// Emit either a warning or an error
|
// Emit either a warning or an error
|
||||||
|
@ -66,7 +66,9 @@ impl<'tcx> LateLintPass<'tcx> for IterNotReturningIterator {
|
|||||||
|
|
||||||
fn check_sig(cx: &LateContext<'_>, name: &str, sig: &FnSig<'_>, fn_id: LocalDefId) {
|
fn check_sig(cx: &LateContext<'_>, name: &str, sig: &FnSig<'_>, fn_id: LocalDefId) {
|
||||||
if sig.decl.implicit_self.has_implicit_self() {
|
if sig.decl.implicit_self.has_implicit_self() {
|
||||||
let ret_ty = cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(fn_id).output());
|
let ret_ty = cx
|
||||||
|
.tcx
|
||||||
|
.erase_late_bound_regions(cx.tcx.fn_sig(fn_id).subst_identity().output());
|
||||||
let ret_ty = cx
|
let ret_ty = cx
|
||||||
.tcx
|
.tcx
|
||||||
.try_normalize_erasing_regions(cx.param_env, ret_ty)
|
.try_normalize_erasing_regions(cx.param_env, ret_ty)
|
||||||
|
@ -145,7 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
|
|||||||
if let Some(local_id) = ty_id.as_local();
|
if let Some(local_id) = ty_id.as_local();
|
||||||
let ty_hir_id = cx.tcx.hir().local_def_id_to_hir_id(local_id);
|
let ty_hir_id = cx.tcx.hir().local_def_id_to_hir_id(local_id);
|
||||||
if !is_lint_allowed(cx, LEN_WITHOUT_IS_EMPTY, ty_hir_id);
|
if !is_lint_allowed(cx, LEN_WITHOUT_IS_EMPTY, ty_hir_id);
|
||||||
if let Some(output) = parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).skip_binder());
|
if let Some(output) = parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).subst_identity().skip_binder());
|
||||||
then {
|
then {
|
||||||
let (name, kind) = match cx.tcx.hir().find(ty_hir_id) {
|
let (name, kind) = match cx.tcx.hir().find(ty_hir_id) {
|
||||||
Some(Node::ForeignItem(x)) => (x.ident.name, "extern type"),
|
Some(Node::ForeignItem(x)) => (x.ident.name, "extern type"),
|
||||||
@ -197,7 +197,15 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items
|
|||||||
fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: Symbol) -> bool {
|
fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: Symbol) -> bool {
|
||||||
item.ident.name == name
|
item.ident.name == name
|
||||||
&& if let AssocItemKind::Fn { has_self } = item.kind {
|
&& if let AssocItemKind::Fn { has_self } = item.kind {
|
||||||
has_self && { cx.tcx.fn_sig(item.id.owner_id).inputs().skip_binder().len() == 1 }
|
has_self && {
|
||||||
|
cx.tcx
|
||||||
|
.fn_sig(item.id.owner_id)
|
||||||
|
.skip_binder()
|
||||||
|
.inputs()
|
||||||
|
.skip_binder()
|
||||||
|
.len()
|
||||||
|
== 1
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -225,7 +233,7 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items
|
|||||||
.any(|i| {
|
.any(|i| {
|
||||||
i.kind == ty::AssocKind::Fn
|
i.kind == ty::AssocKind::Fn
|
||||||
&& i.fn_has_self_parameter
|
&& i.fn_has_self_parameter
|
||||||
&& cx.tcx.fn_sig(i.def_id).inputs().skip_binder().len() == 1
|
&& cx.tcx.fn_sig(i.def_id).skip_binder().inputs().skip_binder().len() == 1
|
||||||
});
|
});
|
||||||
|
|
||||||
if !is_empty_method_found {
|
if !is_empty_method_found {
|
||||||
@ -343,7 +351,11 @@ fn check_for_is_empty<'tcx>(
|
|||||||
),
|
),
|
||||||
Some(is_empty)
|
Some(is_empty)
|
||||||
if !(is_empty.fn_has_self_parameter
|
if !(is_empty.fn_has_self_parameter
|
||||||
&& check_is_empty_sig(cx.tcx.fn_sig(is_empty.def_id).skip_binder(), self_kind, output)) =>
|
&& check_is_empty_sig(
|
||||||
|
cx.tcx.fn_sig(is_empty.def_id).subst_identity().skip_binder(),
|
||||||
|
self_kind,
|
||||||
|
output,
|
||||||
|
)) =>
|
||||||
{
|
{
|
||||||
(
|
(
|
||||||
format!(
|
format!(
|
||||||
@ -474,7 +486,7 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||||||
/// Gets an `AssocItem` and return true if it matches `is_empty(self)`.
|
/// Gets an `AssocItem` and return true if it matches `is_empty(self)`.
|
||||||
fn is_is_empty(cx: &LateContext<'_>, item: &ty::AssocItem) -> bool {
|
fn is_is_empty(cx: &LateContext<'_>, item: &ty::AssocItem) -> bool {
|
||||||
if item.kind == ty::AssocKind::Fn {
|
if item.kind == ty::AssocKind::Fn {
|
||||||
let sig = cx.tcx.fn_sig(item.def_id);
|
let sig = cx.tcx.fn_sig(item.def_id).skip_binder();
|
||||||
let ty = sig.skip_binder();
|
let ty = sig.skip_binder();
|
||||||
ty.inputs().len() == 1
|
ty.inputs().len() == 1
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#![feature(array_windows)]
|
#![feature(array_windows)]
|
||||||
#![feature(binary_heap_into_iter_sorted)]
|
#![feature(binary_heap_into_iter_sorted)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(control_flow_enum)]
|
|
||||||
#![feature(drain_filter)]
|
#![feature(drain_filter)]
|
||||||
#![feature(iter_intersperse)]
|
#![feature(iter_intersperse)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
|
@ -144,7 +144,7 @@ fn check_fn_inner<'tcx>(
|
|||||||
.filter(|param| matches!(param.kind, GenericParamKind::Type { .. }));
|
.filter(|param| matches!(param.kind, GenericParamKind::Type { .. }));
|
||||||
|
|
||||||
for typ in types {
|
for typ in types {
|
||||||
for pred in generics.bounds_for_param(cx.tcx.hir().local_def_id(typ.hir_id)) {
|
for pred in generics.bounds_for_param(typ.def_id) {
|
||||||
if pred.origin == PredicateOrigin::WhereClause {
|
if pred.origin == PredicateOrigin::WhereClause {
|
||||||
// has_where_lifetimes checked that this predicate contains no lifetime.
|
// has_where_lifetimes checked that this predicate contains no lifetime.
|
||||||
continue;
|
continue;
|
||||||
|
@ -370,7 +370,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
|||||||
ExprKind::MethodCall(_, receiver, args, _) => {
|
ExprKind::MethodCall(_, receiver, args, _) => {
|
||||||
let def_id = self.cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
|
let def_id = self.cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
|
||||||
for (ty, expr) in iter::zip(
|
for (ty, expr) in iter::zip(
|
||||||
self.cx.tcx.fn_sig(def_id).inputs().skip_binder(),
|
self.cx.tcx.fn_sig(def_id).subst_identity().inputs().skip_binder(),
|
||||||
std::iter::once(receiver).chain(args.iter()),
|
std::iter::once(receiver).chain(args.iter()),
|
||||||
) {
|
) {
|
||||||
self.prefer_mutable = false;
|
self.prefer_mutable = false;
|
||||||
|
@ -6,10 +6,11 @@ use rustc_errors::Applicability;
|
|||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
AsyncGeneratorKind, Block, Body, Closure, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound,
|
AsyncGeneratorKind, Block, Body, Closure, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound,
|
||||||
HirId, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
|
ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::{sym, Span};
|
use rustc_span::{sym, Span};
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
@ -45,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
|
|||||||
decl: &'tcx FnDecl<'_>,
|
decl: &'tcx FnDecl<'_>,
|
||||||
body: &'tcx Body<'_>,
|
body: &'tcx Body<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
_: HirId,
|
_: LocalDefId,
|
||||||
) {
|
) {
|
||||||
if_chain! {
|
if_chain! {
|
||||||
if let Some(header) = kind.header();
|
if let Some(header) = kind.header();
|
||||||
|
@ -157,11 +157,10 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
|
|||||||
&& def.variants.len() > 1
|
&& def.variants.len() > 1
|
||||||
{
|
{
|
||||||
let mut iter = def.variants.iter().filter_map(|v| {
|
let mut iter = def.variants.iter().filter_map(|v| {
|
||||||
let id = cx.tcx.hir().local_def_id(v.hir_id);
|
(matches!(v.data, hir::VariantData::Unit(_, _))
|
||||||
(matches!(v.data, hir::VariantData::Unit(..))
|
|
||||||
&& v.ident.as_str().starts_with('_')
|
&& v.ident.as_str().starts_with('_')
|
||||||
&& is_doc_hidden(cx.tcx.hir().attrs(v.hir_id)))
|
&& is_doc_hidden(cx.tcx.hir().attrs(v.hir_id)))
|
||||||
.then_some((id, v.span))
|
.then_some((v.def_id, v.span))
|
||||||
});
|
});
|
||||||
if let Some((id, span)) = iter.next()
|
if let Some((id, span)) = iter.next()
|
||||||
&& iter.next().is_none()
|
&& iter.next().is_none()
|
||||||
|
@ -104,7 +104,7 @@ fn is_unit_function(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
|
|||||||
let ty = cx.typeck_results().expr_ty(expr);
|
let ty = cx.typeck_results().expr_ty(expr);
|
||||||
|
|
||||||
if let ty::FnDef(id, _) = *ty.kind() {
|
if let ty::FnDef(id, _) = *ty.kind() {
|
||||||
if let Some(fn_type) = cx.tcx.fn_sig(id).no_bound_vars() {
|
if let Some(fn_type) = cx.tcx.fn_sig(id).subst_identity().no_bound_vars() {
|
||||||
return is_unit_type(fn_type.output());
|
return is_unit_type(fn_type.output());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ fn collect_replace_calls<'tcx>(
|
|||||||
from_args.push_front(from);
|
from_args.push_front(from);
|
||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
} else {
|
} else {
|
||||||
ControlFlow::BREAK
|
ControlFlow::Break(())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
|
@ -70,7 +70,7 @@ pub(super) fn check<'tcx>(
|
|||||||
if let hir::ExprKind::Path(ref p) = fun.kind {
|
if let hir::ExprKind::Path(ref p) = fun.kind {
|
||||||
match cx.qpath_res(p, fun.hir_id) {
|
match cx.qpath_res(p, fun.hir_id) {
|
||||||
hir::def::Res::Def(hir::def::DefKind::Fn | hir::def::DefKind::AssocFn, def_id) => matches!(
|
hir::def::Res::Def(hir::def::DefKind::Fn | hir::def::DefKind::AssocFn, def_id) => matches!(
|
||||||
cx.tcx.fn_sig(def_id).output().skip_binder().kind(),
|
cx.tcx.fn_sig(def_id).subst_identity().output().skip_binder().kind(),
|
||||||
ty::Ref(re, ..) if re.is_static(),
|
ty::Ref(re, ..) if re.is_static(),
|
||||||
),
|
),
|
||||||
_ => false,
|
_ => false,
|
||||||
@ -84,7 +84,7 @@ pub(super) fn check<'tcx>(
|
|||||||
.type_dependent_def_id(arg.hir_id)
|
.type_dependent_def_id(arg.hir_id)
|
||||||
.map_or(false, |method_id| {
|
.map_or(false, |method_id| {
|
||||||
matches!(
|
matches!(
|
||||||
cx.tcx.fn_sig(method_id).output().skip_binder().kind(),
|
cx.tcx.fn_sig(method_id).subst_identity().output().skip_binder().kind(),
|
||||||
ty::Ref(re, ..) if re.is_static()
|
ty::Ref(re, ..) if re.is_static()
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -3353,7 +3353,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
|||||||
|
|
||||||
let implements_trait = matches!(item.kind, hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }));
|
let implements_trait = matches!(item.kind, hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }));
|
||||||
if let hir::ImplItemKind::Fn(ref sig, id) = impl_item.kind {
|
if let hir::ImplItemKind::Fn(ref sig, id) = impl_item.kind {
|
||||||
let method_sig = cx.tcx.fn_sig(impl_item.owner_id);
|
let method_sig = cx.tcx.fn_sig(impl_item.owner_id).subst_identity();
|
||||||
let method_sig = cx.tcx.erase_late_bound_regions(method_sig);
|
let method_sig = cx.tcx.erase_late_bound_regions(method_sig);
|
||||||
let first_arg_ty_opt = method_sig.inputs().iter().next().copied();
|
let first_arg_ty_opt = method_sig.inputs().iter().next().copied();
|
||||||
// if this impl block implements a trait, lint in trait definition instead
|
// if this impl block implements a trait, lint in trait definition instead
|
||||||
@ -3413,7 +3413,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let hir::ImplItemKind::Fn(_, _) = impl_item.kind {
|
if let hir::ImplItemKind::Fn(_, _) = impl_item.kind {
|
||||||
let ret_ty = return_ty(cx, impl_item.hir_id());
|
let ret_ty = return_ty(cx, impl_item.owner_id);
|
||||||
|
|
||||||
if contains_ty_adt_constructor_opaque(cx, ret_ty, self_ty) {
|
if contains_ty_adt_constructor_opaque(cx, ret_ty, self_ty) {
|
||||||
return;
|
return;
|
||||||
@ -3461,7 +3461,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
|||||||
if_chain! {
|
if_chain! {
|
||||||
if item.ident.name == sym::new;
|
if item.ident.name == sym::new;
|
||||||
if let TraitItemKind::Fn(_, _) = item.kind;
|
if let TraitItemKind::Fn(_, _) = item.kind;
|
||||||
let ret_ty = return_ty(cx, item.hir_id());
|
let ret_ty = return_ty(cx, item.owner_id);
|
||||||
let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id())
|
let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id())
|
||||||
.self_ty()
|
.self_ty()
|
||||||
.skip_binder();
|
.skip_binder();
|
||||||
|
@ -137,7 +137,7 @@ pub(super) fn check<'tcx>(
|
|||||||
/// Checks if the given method call matches the expected signature of `([&[mut]] self) -> bool`
|
/// Checks if the given method call matches the expected signature of `([&[mut]] self) -> bool`
|
||||||
fn is_is_empty_sig(cx: &LateContext<'_>, call_id: HirId) -> bool {
|
fn is_is_empty_sig(cx: &LateContext<'_>, call_id: HirId) -> bool {
|
||||||
cx.typeck_results().type_dependent_def_id(call_id).map_or(false, |id| {
|
cx.typeck_results().type_dependent_def_id(call_id).map_or(false, |id| {
|
||||||
let sig = cx.tcx.fn_sig(id).skip_binder();
|
let sig = cx.tcx.fn_sig(id).subst_identity().skip_binder();
|
||||||
sig.inputs().len() == 1 && sig.output().is_bool()
|
sig.inputs().len() == 1 && sig.output().is_bool()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty:
|
|||||||
fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -> bool {
|
fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -> bool {
|
||||||
let typeck = cx.typeck_results();
|
let typeck = cx.typeck_results();
|
||||||
if let Some(id) = typeck.type_dependent_def_id(call_id)
|
if let Some(id) = typeck.type_dependent_def_id(call_id)
|
||||||
&& let sig = cx.tcx.fn_sig(id)
|
&& let sig = cx.tcx.fn_sig(id).subst_identity()
|
||||||
&& sig.skip_binder().output().is_bool()
|
&& sig.skip_binder().output().is_bool()
|
||||||
&& let [_, search_ty] = *sig.skip_binder().inputs()
|
&& let [_, search_ty] = *sig.skip_binder().inputs()
|
||||||
&& let ty::Ref(_, search_ty, Mutability::Not) = *cx.tcx.erase_late_bound_regions(sig.rebind(search_ty)).kind()
|
&& let ty::Ref(_, search_ty, Mutability::Not) = *cx.tcx.erase_late_bound_regions(sig.rebind(search_ty)).kind()
|
||||||
|
@ -11,10 +11,8 @@ use super::SUSPICIOUS_MAP;
|
|||||||
pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, count_recv: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) {
|
pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, count_recv: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) {
|
||||||
if_chain! {
|
if_chain! {
|
||||||
if is_trait_method(cx, count_recv, sym::Iterator);
|
if is_trait_method(cx, count_recv, sym::Iterator);
|
||||||
let closure = expr_or_init(cx, map_arg);
|
if let hir::ExprKind::Closure(closure) = expr_or_init(cx, map_arg).kind;
|
||||||
if let Some(def_id) = cx.tcx.hir().opt_local_def_id(closure.hir_id);
|
let closure_body = cx.tcx.hir().body(closure.body);
|
||||||
if let Some(body_id) = cx.tcx.hir().maybe_body_owned_by(def_id);
|
|
||||||
let closure_body = cx.tcx.hir().body(body_id);
|
|
||||||
if !cx.typeck_results().expr_ty(closure_body.value).is_unit();
|
if !cx.typeck_results().expr_ty(closure_body.value).is_unit();
|
||||||
then {
|
then {
|
||||||
if let Some(map_mutated_vars) = mutated_variables(closure_body.value, cx) {
|
if let Some(map_mutated_vars) = mutated_variables(closure_body.value, cx) {
|
||||||
|
@ -246,7 +246,7 @@ fn check_other_call_arg<'tcx>(
|
|||||||
if_chain! {
|
if_chain! {
|
||||||
if let Some((maybe_call, maybe_arg)) = skip_addr_of_ancestors(cx, expr);
|
if let Some((maybe_call, maybe_arg)) = skip_addr_of_ancestors(cx, expr);
|
||||||
if let Some((callee_def_id, _, recv, call_args)) = get_callee_substs_and_args(cx, maybe_call);
|
if let Some((callee_def_id, _, recv, call_args)) = get_callee_substs_and_args(cx, maybe_call);
|
||||||
let fn_sig = cx.tcx.fn_sig(callee_def_id).skip_binder();
|
let fn_sig = cx.tcx.fn_sig(callee_def_id).subst_identity().skip_binder();
|
||||||
if let Some(i) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == maybe_arg.hir_id);
|
if let Some(i) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == maybe_arg.hir_id);
|
||||||
if let Some(input) = fn_sig.inputs().get(i);
|
if let Some(input) = fn_sig.inputs().get(i);
|
||||||
let (input, n_refs) = peel_mid_ty_refs(*input);
|
let (input, n_refs) = peel_mid_ty_refs(*input);
|
||||||
@ -368,10 +368,9 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
|
|||||||
Node::Block(..) => continue,
|
Node::Block(..) => continue,
|
||||||
Node::Item(item) => {
|
Node::Item(item) => {
|
||||||
if let ItemKind::Fn(_, _, body_id) = &item.kind
|
if let ItemKind::Fn(_, _, body_id) = &item.kind
|
||||||
&& let output_ty = return_ty(cx, item.hir_id())
|
&& let output_ty = return_ty(cx, item.owner_id)
|
||||||
&& let local_def_id = cx.tcx.hir().local_def_id(item.hir_id())
|
&& Inherited::build(cx.tcx, item.owner_id.def_id).enter(|inherited| {
|
||||||
&& Inherited::build(cx.tcx, local_def_id).enter(|inherited| {
|
let fn_ctxt = FnCtxt::new(inherited, cx.param_env, item.owner_id.def_id);
|
||||||
let fn_ctxt = FnCtxt::new(inherited, cx.param_env, local_def_id);
|
|
||||||
fn_ctxt.can_coerce(ty, output_ty)
|
fn_ctxt.can_coerce(ty, output_ty)
|
||||||
}) {
|
}) {
|
||||||
if has_lifetime(output_ty) && has_lifetime(ty) {
|
if has_lifetime(output_ty) && has_lifetime(ty) {
|
||||||
@ -386,7 +385,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
|
|||||||
Node::Expr(parent_expr) => {
|
Node::Expr(parent_expr) => {
|
||||||
if let Some((callee_def_id, call_substs, recv, call_args)) = get_callee_substs_and_args(cx, parent_expr)
|
if let Some((callee_def_id, call_substs, recv, call_args)) = get_callee_substs_and_args(cx, parent_expr)
|
||||||
{
|
{
|
||||||
let fn_sig = cx.tcx.fn_sig(callee_def_id).skip_binder();
|
let fn_sig = cx.tcx.fn_sig(callee_def_id).subst_identity().skip_binder();
|
||||||
if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id)
|
if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id)
|
||||||
&& let Some(param_ty) = fn_sig.inputs().get(arg_index)
|
&& let Some(param_ty) = fn_sig.inputs().get(arg_index)
|
||||||
&& let ty::Param(ParamTy { index: param_index , ..}) = param_ty.kind()
|
&& let ty::Param(ParamTy { index: param_index , ..}) = param_ty.kind()
|
||||||
|
@ -4,12 +4,13 @@ use if_chain::if_chain;
|
|||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
self as hir, def, BinOpKind, BindingAnnotation, Body, ByRef, Expr, ExprKind, FnDecl, HirId, Mutability, PatKind,
|
self as hir, def, BinOpKind, BindingAnnotation, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, Stmt,
|
||||||
Stmt, StmtKind, TyKind,
|
StmtKind, TyKind,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::hygiene::DesugaringKind;
|
use rustc_span::hygiene::DesugaringKind;
|
||||||
use rustc_span::source_map::{ExpnKind, Span};
|
use rustc_span::source_map::{ExpnKind, Span};
|
||||||
|
|
||||||
@ -151,7 +152,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
|
|||||||
decl: &'tcx FnDecl<'_>,
|
decl: &'tcx FnDecl<'_>,
|
||||||
body: &'tcx Body<'_>,
|
body: &'tcx Body<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
_: HirId,
|
_: LocalDefId,
|
||||||
) {
|
) {
|
||||||
if let FnKind::Closure = k {
|
if let FnKind::Closure = k {
|
||||||
// Does not apply to closures
|
// Does not apply to closures
|
||||||
|
@ -6,11 +6,12 @@ use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_ma
|
|||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::CRATE_DEF_ID;
|
use rustc_hir::def_id::CRATE_DEF_ID;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{Body, Constness, FnDecl, GenericParamKind, HirId};
|
use rustc_hir::{Body, Constness, FnDecl, GenericParamKind};
|
||||||
use rustc_hir_analysis::hir_ty_to_ty;
|
use rustc_hir_analysis::hir_ty_to_ty;
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
@ -91,14 +92,12 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
|
|||||||
_: &FnDecl<'_>,
|
_: &FnDecl<'_>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
hir_id: HirId,
|
def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
if !self.msrv.meets(msrvs::CONST_IF_MATCH) {
|
if !self.msrv.meets(msrvs::CONST_IF_MATCH) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let def_id = cx.tcx.hir().local_def_id(hir_id);
|
|
||||||
|
|
||||||
if in_external_macro(cx.tcx.sess, span) || is_entrypoint_fn(cx, def_id.to_def_id()) {
|
if in_external_macro(cx.tcx.sess, span) || is_entrypoint_fn(cx, def_id.to_def_id()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -132,6 +131,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
|
|||||||
FnKind::Closure => return,
|
FnKind::Closure => return,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
|
|
||||||
// Const fns are not allowed as methods in a trait.
|
// Const fns are not allowed as methods in a trait.
|
||||||
{
|
{
|
||||||
let parent = cx.tcx.hir().get_parent_item(hir_id).def_id;
|
let parent = cx.tcx.hir().get_parent_item(hir_id).def_id;
|
||||||
|
@ -128,7 +128,7 @@ fn collect_unsafe_exprs<'tcx>(
|
|||||||
..
|
..
|
||||||
},
|
},
|
||||||
)) if kind.is_fn_like() => {
|
)) if kind.is_fn_like() => {
|
||||||
let sig = cx.tcx.bound_fn_sig(*def_id);
|
let sig = cx.tcx.fn_sig(*def_id);
|
||||||
if sig.0.unsafety() == Unsafety::Unsafe {
|
if sig.0.unsafety() == Unsafety::Unsafe {
|
||||||
unsafe_ops.push(("unsafe function call occurs here", expr.span));
|
unsafe_ops.push(("unsafe function call occurs here", expr.span));
|
||||||
}
|
}
|
||||||
@ -138,7 +138,7 @@ fn collect_unsafe_exprs<'tcx>(
|
|||||||
if let Some(sig) = cx
|
if let Some(sig) = cx
|
||||||
.typeck_results()
|
.typeck_results()
|
||||||
.type_dependent_def_id(path_expr.hir_id)
|
.type_dependent_def_id(path_expr.hir_id)
|
||||||
.map(|def_id| cx.tcx.bound_fn_sig(def_id))
|
.map(|def_id| cx.tcx.fn_sig(def_id))
|
||||||
{
|
{
|
||||||
if sig.0.unsafety() == Unsafety::Unsafe {
|
if sig.0.unsafety() == Unsafety::Unsafe {
|
||||||
unsafe_ops.push(("unsafe function call occurs here", expr.span));
|
unsafe_ops.push(("unsafe function call occurs here", expr.span));
|
||||||
@ -153,7 +153,7 @@ fn collect_unsafe_exprs<'tcx>(
|
|||||||
if let Some(sig) = cx
|
if let Some(sig) = cx
|
||||||
.typeck_results()
|
.typeck_results()
|
||||||
.type_dependent_def_id(expr.hir_id)
|
.type_dependent_def_id(expr.hir_id)
|
||||||
.map(|def_id| cx.tcx.bound_fn_sig(def_id))
|
.map(|def_id| cx.tcx.fn_sig(def_id))
|
||||||
{
|
{
|
||||||
if sig.0.unsafety() == Unsafety::Unsafe {
|
if sig.0.unsafety() == Unsafety::Unsafe {
|
||||||
unsafe_ops.push(("unsafe method call occurs here", expr.span));
|
unsafe_ops.push(("unsafe method call occurs here", expr.span));
|
||||||
|
@ -6,6 +6,7 @@ use rustc_lint::{LateContext, LateLintPass};
|
|||||||
use rustc_middle::ty::TypeVisitable;
|
use rustc_middle::ty::TypeVisitable;
|
||||||
use rustc_middle::ty::{Adt, Array, Ref, Slice, Tuple, Ty};
|
use rustc_middle::ty::{Adt, Array, Ref, Slice, Tuple, Ty};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
@ -102,21 +103,21 @@ impl<'tcx> LateLintPass<'tcx> for MutableKeyType {
|
|||||||
|
|
||||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||||
if let hir::ItemKind::Fn(ref sig, ..) = item.kind {
|
if let hir::ItemKind::Fn(ref sig, ..) = item.kind {
|
||||||
self.check_sig(cx, item.hir_id(), sig.decl);
|
self.check_sig(cx, item.owner_id.def_id, sig.decl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'tcx>) {
|
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'tcx>) {
|
||||||
if let hir::ImplItemKind::Fn(ref sig, ..) = item.kind {
|
if let hir::ImplItemKind::Fn(ref sig, ..) = item.kind {
|
||||||
if trait_ref_of_method(cx, item.owner_id.def_id).is_none() {
|
if trait_ref_of_method(cx, item.owner_id.def_id).is_none() {
|
||||||
self.check_sig(cx, item.hir_id(), sig.decl);
|
self.check_sig(cx, item.owner_id.def_id, sig.decl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'tcx>) {
|
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'tcx>) {
|
||||||
if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
|
if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
|
||||||
self.check_sig(cx, item.hir_id(), sig.decl);
|
self.check_sig(cx, item.owner_id.def_id, sig.decl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,9 +137,8 @@ impl MutableKeyType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_sig(&self, cx: &LateContext<'_>, item_hir_id: hir::HirId, decl: &hir::FnDecl<'_>) {
|
fn check_sig(&self, cx: &LateContext<'_>, fn_def_id: LocalDefId, decl: &hir::FnDecl<'_>) {
|
||||||
let fn_def_id = cx.tcx.hir().local_def_id(item_hir_id);
|
let fn_sig = cx.tcx.fn_sig(fn_def_id).subst_identity();
|
||||||
let fn_sig = cx.tcx.fn_sig(fn_def_id);
|
|
||||||
for (hir_ty, ty) in iter::zip(decl.inputs, fn_sig.inputs().skip_binder()) {
|
for (hir_ty, ty) in iter::zip(decl.inputs, fn_sig.inputs().skip_binder()) {
|
||||||
self.check_ty_(cx, hir_ty.span, *ty);
|
self.check_ty_(cx, hir_ty.span, *ty);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ use rustc_lint::{LateContext, LateLintPass};
|
|||||||
use rustc_middle::mir::FakeReadCause;
|
use rustc_middle::mir::FakeReadCause;
|
||||||
use rustc_middle::ty::{self, TypeVisitable};
|
use rustc_middle::ty::{self, TypeVisitable};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::symbol::kw;
|
use rustc_span::symbol::kw;
|
||||||
use rustc_span::{sym, Span};
|
use rustc_span::{sym, Span};
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
@ -82,12 +83,14 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
|
|||||||
decl: &'tcx FnDecl<'_>,
|
decl: &'tcx FnDecl<'_>,
|
||||||
body: &'tcx Body<'_>,
|
body: &'tcx Body<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
hir_id: HirId,
|
fn_def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
if span.from_expansion() {
|
if span.from_expansion() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(fn_def_id);
|
||||||
|
|
||||||
match kind {
|
match kind {
|
||||||
FnKind::ItemFn(.., header) => {
|
FnKind::ItemFn(.., header) => {
|
||||||
let attrs = cx.tcx.hir().attrs(hir_id);
|
let attrs = cx.tcx.hir().attrs(hir_id);
|
||||||
@ -119,8 +122,6 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
|
|||||||
|
|
||||||
let sized_trait = need!(cx.tcx.lang_items().sized_trait());
|
let sized_trait = need!(cx.tcx.lang_items().sized_trait());
|
||||||
|
|
||||||
let fn_def_id = cx.tcx.hir().local_def_id(hir_id);
|
|
||||||
|
|
||||||
let preds = traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds().iter())
|
let preds = traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds().iter())
|
||||||
.filter(|p| !p.is_global())
|
.filter(|p| !p.is_global())
|
||||||
.filter_map(|obligation| {
|
.filter_map(|obligation| {
|
||||||
@ -147,7 +148,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
|
|||||||
ctx
|
ctx
|
||||||
};
|
};
|
||||||
|
|
||||||
let fn_sig = cx.tcx.fn_sig(fn_def_id);
|
let fn_sig = cx.tcx.fn_sig(fn_def_id).subst_identity();
|
||||||
let fn_sig = cx.tcx.erase_late_bound_regions(fn_sig);
|
let fn_sig = cx.tcx.erase_late_bound_regions(fn_sig);
|
||||||
|
|
||||||
for (idx, ((input, &ty), arg)) in decl.inputs.iter().zip(fn_sig.inputs()).zip(body.params).enumerate() {
|
for (idx, ((input, &ty), arg)) in decl.inputs.iter().zip(fn_sig.inputs()).zip(body.params).enumerate() {
|
||||||
|
@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
|
|||||||
}
|
}
|
||||||
if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind {
|
if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind {
|
||||||
let name = impl_item.ident.name;
|
let name = impl_item.ident.name;
|
||||||
let id = impl_item.hir_id();
|
let id = impl_item.owner_id;
|
||||||
if sig.header.constness == hir::Constness::Const {
|
if sig.header.constness == hir::Constness::Const {
|
||||||
// can't be implemented by default
|
// can't be implemented by default
|
||||||
return;
|
return;
|
||||||
@ -97,7 +97,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
|
|||||||
if sig.decl.inputs.is_empty();
|
if sig.decl.inputs.is_empty();
|
||||||
if name == sym::new;
|
if name == sym::new;
|
||||||
if cx.effective_visibilities.is_reachable(impl_item.owner_id.def_id);
|
if cx.effective_visibilities.is_reachable(impl_item.owner_id.def_id);
|
||||||
let self_def_id = cx.tcx.hir().get_parent_item(id);
|
let self_def_id = cx.tcx.hir().get_parent_item(id.into());
|
||||||
let self_ty = cx.tcx.type_of(self_def_id);
|
let self_ty = cx.tcx.type_of(self_def_id);
|
||||||
if 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);
|
if let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default);
|
||||||
@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
|
|||||||
span_lint_hir_and_then(
|
span_lint_hir_and_then(
|
||||||
cx,
|
cx,
|
||||||
NEW_WITHOUT_DEFAULT,
|
NEW_WITHOUT_DEFAULT,
|
||||||
id,
|
id.into(),
|
||||||
impl_item.span,
|
impl_item.span,
|
||||||
&format!(
|
&format!(
|
||||||
"you should consider adding a `Default` implementation for `{self_type_snip}`"
|
"you should consider adding a `Default` implementation for `{self_type_snip}`"
|
||||||
|
@ -209,7 +209,8 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
|
|||||||
|
|
||||||
fn check_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {
|
fn check_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {
|
||||||
let body_owner = cx.tcx.hir().body_owner(body.id());
|
let body_owner = cx.tcx.hir().body_owner(body.id());
|
||||||
let body_owner_def_id = cx.tcx.hir().local_def_id(body_owner);
|
let body_owner_def_id = cx.tcx.hir().body_owner_def_id(body.id());
|
||||||
|
|
||||||
let body_owner_kind = cx.tcx.hir().body_owner_kind(body_owner_def_id);
|
let body_owner_kind = cx.tcx.hir().body_owner_kind(body_owner_def_id);
|
||||||
if let hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) = body_owner_kind {
|
if let hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) = body_owner_kind {
|
||||||
let body_span = cx.tcx.hir().span_with_body(body_owner);
|
let body_span = cx.tcx.hir().span_with_body(body_owner);
|
||||||
|
@ -96,7 +96,7 @@ impl Context {
|
|||||||
|
|
||||||
pub fn enter_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {
|
pub fn enter_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {
|
||||||
let body_owner = cx.tcx.hir().body_owner(body.id());
|
let body_owner = cx.tcx.hir().body_owner(body.id());
|
||||||
let body_owner_def_id = cx.tcx.hir().local_def_id(body_owner);
|
let body_owner_def_id = cx.tcx.hir().body_owner_def_id(body.id());
|
||||||
|
|
||||||
match cx.tcx.hir().body_owner_kind(body_owner_def_id) {
|
match cx.tcx.hir().body_owner_kind(body_owner_def_id) {
|
||||||
hir::BodyOwnerKind::Static(_) | hir::BodyOwnerKind::Const => {
|
hir::BodyOwnerKind::Static(_) | hir::BodyOwnerKind::Const => {
|
||||||
|
@ -8,6 +8,7 @@ use rustc_hir as hir;
|
|||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::{sym, Span};
|
use rustc_span::{sym, Span};
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
@ -49,9 +50,13 @@ impl<'tcx> LateLintPass<'tcx> for PanicInResultFn {
|
|||||||
_: &'tcx hir::FnDecl<'tcx>,
|
_: &'tcx hir::FnDecl<'tcx>,
|
||||||
body: &'tcx hir::Body<'tcx>,
|
body: &'tcx hir::Body<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
hir_id: hir::HirId,
|
def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
if !matches!(fn_kind, FnKind::Closure) && is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::Result) {
|
if matches!(fn_kind, FnKind::Closure) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let owner = cx.tcx.hir().local_def_id_to_hir_id(def_id).expect_owner();
|
||||||
|
if is_type_diagnostic_item(cx, return_ty(cx, owner), sym::Result) {
|
||||||
lint_impl_body(cx, span, body);
|
lint_impl_body(cx, span, body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use rustc_data_structures::fx::FxHashSet;
|
|||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{BindingAnnotation, Body, FnDecl, HirId, Impl, ItemKind, MutTy, Mutability, Node, PatKind};
|
use rustc_hir::{BindingAnnotation, Body, FnDecl, Impl, ItemKind, MutTy, Mutability, Node, PatKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::ty::adjustment::{Adjust, PointerCast};
|
use rustc_middle::ty::adjustment::{Adjust, PointerCast};
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
@ -143,7 +143,7 @@ impl<'tcx> PassByRefOrValue {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let fn_sig = cx.tcx.fn_sig(def_id);
|
let fn_sig = cx.tcx.fn_sig(def_id).subst_identity();
|
||||||
let fn_body = cx.enclosing_body.map(|id| cx.tcx.hir().body(id));
|
let fn_body = cx.enclosing_body.map(|id| cx.tcx.hir().body(id));
|
||||||
|
|
||||||
// Gather all the lifetimes found in the output type which may affect whether
|
// Gather all the lifetimes found in the output type which may affect whether
|
||||||
@ -272,12 +272,13 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
|
|||||||
decl: &'tcx FnDecl<'_>,
|
decl: &'tcx FnDecl<'_>,
|
||||||
_body: &'tcx Body<'_>,
|
_body: &'tcx Body<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
hir_id: HirId,
|
def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
if span.from_expansion() {
|
if span.from_expansion() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
match kind {
|
match kind {
|
||||||
FnKind::ItemFn(.., header) => {
|
FnKind::ItemFn(.., header) => {
|
||||||
if header.abi != Abi::Rust {
|
if header.abi != Abi::Rust {
|
||||||
@ -308,6 +309,6 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.check_poly_fn(cx, cx.tcx.hir().local_def_id(hir_id), decl, Some(span));
|
self.check_poly_fn(cx, def_id, decl, Some(span));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_help;
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
use rustc_hir::{
|
use rustc_hir::{intravisit, Body, Expr, ExprKind, FnDecl, Let, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind};
|
||||||
intravisit, Body, Expr, ExprKind, FnDecl, HirId, Let, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind,
|
|
||||||
};
|
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
@ -116,7 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch {
|
|||||||
_: &'tcx FnDecl<'_>,
|
_: &'tcx FnDecl<'_>,
|
||||||
body: &'tcx Body<'_>,
|
body: &'tcx Body<'_>,
|
||||||
_: Span,
|
_: Span,
|
||||||
_: HirId,
|
_: LocalDefId,
|
||||||
) {
|
) {
|
||||||
for param in body.params {
|
for param in body.params {
|
||||||
apply_lint(cx, param.pat, DerefPossible::Impossible);
|
apply_lint(cx, param.pat, DerefPossible::Impossible);
|
||||||
|
@ -164,7 +164,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
|
|||||||
check_mut_from_ref(cx, sig, None);
|
check_mut_from_ref(cx, sig, None);
|
||||||
for arg in check_fn_args(
|
for arg in check_fn_args(
|
||||||
cx,
|
cx,
|
||||||
cx.tcx.fn_sig(item.owner_id).skip_binder().inputs(),
|
cx.tcx.fn_sig(item.owner_id).subst_identity().skip_binder().inputs(),
|
||||||
sig.decl.inputs,
|
sig.decl.inputs,
|
||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
@ -217,7 +217,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
|
|||||||
|
|
||||||
check_mut_from_ref(cx, sig, Some(body));
|
check_mut_from_ref(cx, sig, Some(body));
|
||||||
let decl = sig.decl;
|
let decl = sig.decl;
|
||||||
let sig = cx.tcx.fn_sig(item_id).skip_binder();
|
let sig = cx.tcx.fn_sig(item_id).subst_identity().skip_binder();
|
||||||
let lint_args: Vec<_> = check_fn_args(cx, sig.inputs(), decl.inputs, body.params)
|
let lint_args: Vec<_> = check_fn_args(cx, sig.inputs(), decl.inputs, body.params)
|
||||||
.filter(|arg| !is_trait_item || arg.mutability() == Mutability::Not)
|
.filter(|arg| !is_trait_item || arg.mutability() == Mutability::Not)
|
||||||
.collect();
|
.collect();
|
||||||
@ -624,7 +624,10 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
match *self.cx.tcx.fn_sig(id).skip_binder().inputs()[i].peel_refs().kind() {
|
match *self.cx.tcx.fn_sig(id).subst_identity().skip_binder().inputs()[i]
|
||||||
|
.peel_refs()
|
||||||
|
.kind()
|
||||||
|
{
|
||||||
ty::Dynamic(preds, _, _) if !matches_preds(self.cx, args.deref_ty.ty(self.cx), preds) => {
|
ty::Dynamic(preds, _, _) if !matches_preds(self.cx, args.deref_ty.ty(self.cx), preds) => {
|
||||||
set_skip_flag();
|
set_skip_flag();
|
||||||
},
|
},
|
||||||
|
@ -6,11 +6,12 @@ use clippy_utils::{fn_has_unsatisfiable_preds, match_def_path, paths};
|
|||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{def_id, Body, FnDecl, HirId, LangItem};
|
use rustc_hir::{def_id, Body, FnDecl, LangItem};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::source_map::{BytePos, Span};
|
use rustc_span::source_map::{BytePos, Span};
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
|
||||||
@ -69,12 +70,10 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
|
|||||||
cx: &LateContext<'tcx>,
|
cx: &LateContext<'tcx>,
|
||||||
_: FnKind<'tcx>,
|
_: FnKind<'tcx>,
|
||||||
_: &'tcx FnDecl<'_>,
|
_: &'tcx FnDecl<'_>,
|
||||||
body: &'tcx Body<'_>,
|
_: &'tcx Body<'_>,
|
||||||
_: Span,
|
_: Span,
|
||||||
_: HirId,
|
def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
let def_id = cx.tcx.hir().body_owner_def_id(body.id());
|
|
||||||
|
|
||||||
// Building MIR for `fn`s with unsatisfiable preds results in ICE.
|
// Building MIR for `fn`s with unsatisfiable preds results in ICE.
|
||||||
if fn_has_unsatisfiable_preds(cx, def_id.to_def_id()) {
|
if fn_has_unsatisfiable_preds(cx, def_id.to_def_id()) {
|
||||||
return;
|
return;
|
||||||
|
@ -3,7 +3,7 @@ use clippy_utils::ty::is_must_use_ty;
|
|||||||
use clippy_utils::{nth_arg, return_ty};
|
use clippy_utils::{nth_arg, return_ty};
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{Body, FnDecl, HirId, TraitItem, TraitItemKind};
|
use rustc_hir::{Body, FnDecl, OwnerId, TraitItem, TraitItemKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
@ -68,7 +68,7 @@ declare_clippy_lint! {
|
|||||||
|
|
||||||
declare_lint_pass!(ReturnSelfNotMustUse => [RETURN_SELF_NOT_MUST_USE]);
|
declare_lint_pass!(ReturnSelfNotMustUse => [RETURN_SELF_NOT_MUST_USE]);
|
||||||
|
|
||||||
fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, span: Span, hir_id: HirId) {
|
fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, span: Span, owner_id: OwnerId) {
|
||||||
if_chain! {
|
if_chain! {
|
||||||
// If it comes from an external macro, better ignore it.
|
// If it comes from an external macro, better ignore it.
|
||||||
if !in_external_macro(cx.sess(), span);
|
if !in_external_macro(cx.sess(), span);
|
||||||
@ -76,10 +76,10 @@ fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, spa
|
|||||||
// We only show this warning for public exported methods.
|
// We only show this warning for public exported methods.
|
||||||
if cx.effective_visibilities.is_exported(fn_def);
|
if cx.effective_visibilities.is_exported(fn_def);
|
||||||
// We don't want to emit this lint if the `#[must_use]` attribute is already there.
|
// We don't want to emit this lint if the `#[must_use]` attribute is already there.
|
||||||
if !cx.tcx.hir().attrs(hir_id).iter().any(|attr| attr.has_name(sym::must_use));
|
if !cx.tcx.hir().attrs(owner_id.into()).iter().any(|attr| attr.has_name(sym::must_use));
|
||||||
if cx.tcx.visibility(fn_def.to_def_id()).is_public();
|
if cx.tcx.visibility(fn_def.to_def_id()).is_public();
|
||||||
let ret_ty = return_ty(cx, hir_id);
|
let ret_ty = return_ty(cx, owner_id);
|
||||||
let self_arg = nth_arg(cx, hir_id, 0);
|
let self_arg = nth_arg(cx, owner_id, 0);
|
||||||
// If `Self` has the same type as the returned type, then we want to warn.
|
// If `Self` has the same type as the returned type, then we want to warn.
|
||||||
//
|
//
|
||||||
// For this check, we don't want to remove the reference on the returned type because if
|
// For this check, we don't want to remove the reference on the returned type because if
|
||||||
@ -109,26 +109,26 @@ impl<'tcx> LateLintPass<'tcx> for ReturnSelfNotMustUse {
|
|||||||
decl: &'tcx FnDecl<'tcx>,
|
decl: &'tcx FnDecl<'tcx>,
|
||||||
_: &'tcx Body<'tcx>,
|
_: &'tcx Body<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
hir_id: HirId,
|
fn_def: LocalDefId,
|
||||||
) {
|
) {
|
||||||
if_chain! {
|
if_chain! {
|
||||||
// We are only interested in methods, not in functions or associated functions.
|
// We are only interested in methods, not in functions or associated functions.
|
||||||
if matches!(kind, FnKind::Method(_, _));
|
if matches!(kind, FnKind::Method(_, _));
|
||||||
if let Some(fn_def) = cx.tcx.hir().opt_local_def_id(hir_id);
|
|
||||||
if let Some(impl_def) = cx.tcx.impl_of_method(fn_def.to_def_id());
|
if let Some(impl_def) = cx.tcx.impl_of_method(fn_def.to_def_id());
|
||||||
// We don't want this method to be te implementation of a trait because the
|
// We don't want this method to be te implementation of a trait because the
|
||||||
// `#[must_use]` should be put on the trait definition directly.
|
// `#[must_use]` should be put on the trait definition directly.
|
||||||
if cx.tcx.trait_id_of_impl(impl_def).is_none();
|
if cx.tcx.trait_id_of_impl(impl_def).is_none();
|
||||||
|
|
||||||
then {
|
then {
|
||||||
check_method(cx, decl, fn_def, span, hir_id);
|
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(fn_def);
|
||||||
|
check_method(cx, decl, fn_def, span, hir_id.expect_owner());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'tcx>) {
|
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'tcx>) {
|
||||||
if let TraitItemKind::Fn(ref sig, _) = item.kind {
|
if let TraitItemKind::Fn(ref sig, _) = item.kind {
|
||||||
check_method(cx, sig.decl, item.owner_id.def_id, item.span, item.hir_id());
|
check_method(cx, sig.decl, item.owner_id.def_id, item.span, item.owner_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,12 @@ use core::ops::ControlFlow;
|
|||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, HirId, LangItem, MatchSource, PatKind, QPath, StmtKind};
|
use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, LangItem, MatchSource, PatKind, QPath, StmtKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_middle::ty::subst::GenericArgKind;
|
use rustc_middle::ty::subst::GenericArgKind;
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
use rustc_span::{BytePos, Pos};
|
use rustc_span::{BytePos, Pos};
|
||||||
|
|
||||||
@ -152,7 +153,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
|
|||||||
_: &'tcx FnDecl<'tcx>,
|
_: &'tcx FnDecl<'tcx>,
|
||||||
body: &'tcx Body<'tcx>,
|
body: &'tcx Body<'tcx>,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
_: HirId,
|
_: LocalDefId,
|
||||||
) {
|
) {
|
||||||
match kind {
|
match kind {
|
||||||
FnKind::Closure => {
|
FnKind::Closure => {
|
||||||
@ -290,6 +291,7 @@ fn last_statement_borrows<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>)
|
|||||||
&& cx
|
&& cx
|
||||||
.tcx
|
.tcx
|
||||||
.fn_sig(def_id)
|
.fn_sig(def_id)
|
||||||
|
.subst_identity()
|
||||||
.skip_binder()
|
.skip_binder()
|
||||||
.output()
|
.output()
|
||||||
.walk()
|
.walk()
|
||||||
|
@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {
|
|||||||
let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id;
|
let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id;
|
||||||
let item = cx.tcx.hir().expect_item(parent);
|
let item = cx.tcx.hir().expect_item(parent);
|
||||||
let self_ty = cx.tcx.type_of(item.owner_id);
|
let self_ty = cx.tcx.type_of(item.owner_id);
|
||||||
let ret_ty = return_ty(cx, impl_item.hir_id());
|
let ret_ty = return_ty(cx, impl_item.owner_id);
|
||||||
|
|
||||||
// Do not check trait impls
|
// Do not check trait impls
|
||||||
if matches!(item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. })) {
|
if matches!(item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. })) {
|
||||||
|
@ -61,8 +61,7 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'_>, item: &Item<'_
|
|||||||
if let rustc_hir::TyKind::Array(_, rustc_hir::ArrayLen::Body(length)) = last_field.ty.kind;
|
if let rustc_hir::TyKind::Array(_, rustc_hir::ArrayLen::Body(length)) = last_field.ty.kind;
|
||||||
|
|
||||||
// Then check if that that array zero-sized
|
// Then check if that that array zero-sized
|
||||||
let length_ldid = cx.tcx.hir().local_def_id(length.hir_id);
|
let length = Const::from_anon_const(cx.tcx, length.def_id);
|
||||||
let length = Const::from_anon_const(cx.tcx, length_ldid);
|
|
||||||
let length = length.try_eval_usize(cx.tcx, cx.param_env);
|
let length = length.try_eval_usize(cx.tcx, cx.param_env);
|
||||||
if let Some(length) = length;
|
if let Some(length) = length;
|
||||||
then {
|
then {
|
||||||
|
@ -12,11 +12,12 @@ mod vec_box;
|
|||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
Body, FnDecl, FnRetTy, GenericArg, HirId, ImplItem, ImplItemKind, Item, ItemKind, Local, MutTy, QPath, TraitItem,
|
Body, FnDecl, FnRetTy, GenericArg, ImplItem, ImplItemKind, Item, ItemKind, Local, MutTy, QPath, TraitItem,
|
||||||
TraitItemKind, TyKind,
|
TraitItemKind, TyKind,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
@ -311,15 +312,27 @@ pub struct Types {
|
|||||||
impl_lint_pass!(Types => [BOX_COLLECTION, VEC_BOX, OPTION_OPTION, LINKEDLIST, BORROWED_BOX, REDUNDANT_ALLOCATION, RC_BUFFER, RC_MUTEX, TYPE_COMPLEXITY]);
|
impl_lint_pass!(Types => [BOX_COLLECTION, VEC_BOX, OPTION_OPTION, LINKEDLIST, BORROWED_BOX, REDUNDANT_ALLOCATION, RC_BUFFER, RC_MUTEX, TYPE_COMPLEXITY]);
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for Types {
|
impl<'tcx> LateLintPass<'tcx> for Types {
|
||||||
fn check_fn(&mut self, cx: &LateContext<'_>, _: FnKind<'_>, decl: &FnDecl<'_>, _: &Body<'_>, _: Span, id: HirId) {
|
fn check_fn(
|
||||||
let is_in_trait_impl =
|
&mut self,
|
||||||
if let Some(hir::Node::Item(item)) = cx.tcx.hir().find_by_def_id(cx.tcx.hir().get_parent_item(id).def_id) {
|
cx: &LateContext<'_>,
|
||||||
|
_: FnKind<'_>,
|
||||||
|
decl: &FnDecl<'_>,
|
||||||
|
_: &Body<'_>,
|
||||||
|
_: Span,
|
||||||
|
def_id: LocalDefId,
|
||||||
|
) {
|
||||||
|
let is_in_trait_impl = if let Some(hir::Node::Item(item)) = cx.tcx.hir().find_by_def_id(
|
||||||
|
cx.tcx
|
||||||
|
.hir()
|
||||||
|
.get_parent_item(cx.tcx.hir().local_def_id_to_hir_id(def_id))
|
||||||
|
.def_id,
|
||||||
|
) {
|
||||||
matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }))
|
matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }))
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_exported = cx.effective_visibilities.is_exported(cx.tcx.hir().local_def_id(id));
|
let is_exported = cx.effective_visibilities.is_exported(def_id);
|
||||||
|
|
||||||
self.check_fn_decl(
|
self.check_fn_decl(
|
||||||
cx,
|
cx,
|
||||||
@ -379,9 +392,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) {
|
fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) {
|
||||||
let is_exported = cx
|
let is_exported = cx.effective_visibilities.is_exported(field.def_id);
|
||||||
.effective_visibilities
|
|
||||||
.is_exported(cx.tcx.hir().local_def_id(field.hir_id));
|
|
||||||
|
|
||||||
self.check_ty(
|
self.check_ty(
|
||||||
cx,
|
cx,
|
||||||
|
@ -76,7 +76,7 @@ fn get_projection_pred<'tcx>(
|
|||||||
fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Vec<(usize, String)> {
|
fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Vec<(usize, String)> {
|
||||||
let mut args_to_check = Vec::new();
|
let mut args_to_check = Vec::new();
|
||||||
if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
|
if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
|
||||||
let fn_sig = cx.tcx.fn_sig(def_id);
|
let fn_sig = cx.tcx.fn_sig(def_id).subst_identity();
|
||||||
let generics = cx.tcx.predicates_of(def_id);
|
let generics = cx.tcx.predicates_of(def_id);
|
||||||
let fn_mut_preds = get_trait_predicates_for_trait_id(cx, generics, cx.tcx.lang_items().fn_mut_trait());
|
let fn_mut_preds = get_trait_predicates_for_trait_id(cx, generics, cx.tcx.lang_items().fn_mut_trait());
|
||||||
let ord_preds = get_trait_predicates_for_trait_id(cx, generics, cx.tcx.get_diagnostic_item(sym::Ord));
|
let ord_preds = get_trait_predicates_for_trait_id(cx, generics, cx.tcx.get_diagnostic_item(sym::Ord));
|
||||||
|
@ -156,7 +156,7 @@ fn needs_inferred_result_ty(
|
|||||||
},
|
},
|
||||||
_ => return false,
|
_ => return false,
|
||||||
};
|
};
|
||||||
let sig = cx.tcx.fn_sig(id).skip_binder();
|
let sig = cx.tcx.fn_sig(id).subst_identity().skip_binder();
|
||||||
if let ty::Param(output_ty) = *sig.output().kind() {
|
if let ty::Param(output_ty) = *sig.output().kind() {
|
||||||
let args: Vec<&Expr<'_>> = if let Some(receiver) = receiver {
|
let args: Vec<&Expr<'_>> = if let Some(receiver) = receiver {
|
||||||
std::iter::once(receiver).chain(args.iter()).collect()
|
std::iter::once(receiver).chain(args.iter()).collect()
|
||||||
|
@ -5,10 +5,11 @@ use if_chain::if_chain;
|
|||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::LangItem::{OptionSome, ResultOk};
|
use rustc_hir::LangItem::{OptionSome, ResultOk};
|
||||||
use rustc_hir::{Body, ExprKind, FnDecl, HirId, Impl, ItemKind, Node};
|
use rustc_hir::{Body, ExprKind, FnDecl, Impl, ItemKind, Node};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
@ -77,12 +78,11 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
|
|||||||
fn_decl: &FnDecl<'tcx>,
|
fn_decl: &FnDecl<'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
hir_id: HirId,
|
def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
// Abort if public function/method or closure.
|
// Abort if public function/method or closure.
|
||||||
match fn_kind {
|
match fn_kind {
|
||||||
FnKind::ItemFn(..) | FnKind::Method(..) => {
|
FnKind::ItemFn(..) | FnKind::Method(..) => {
|
||||||
let def_id = cx.tcx.hir().local_def_id(hir_id);
|
|
||||||
if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {
|
if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -91,6 +91,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Abort if the method is implementing a trait or of it a trait method.
|
// Abort if the method is implementing a trait or of it a trait method.
|
||||||
|
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) {
|
if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) {
|
||||||
if matches!(
|
if matches!(
|
||||||
item.kind,
|
item.kind,
|
||||||
@ -101,7 +102,8 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the wrapper and inner types, if can't, abort.
|
// Get the wrapper and inner types, if can't, abort.
|
||||||
let (return_type_label, lang_item, inner_type) = if let ty::Adt(adt_def, subst) = return_ty(cx, hir_id).kind() {
|
let (return_type_label, lang_item, inner_type) =
|
||||||
|
if let ty::Adt(adt_def, subst) = return_ty(cx, hir_id.expect_owner()).kind() {
|
||||||
if cx.tcx.is_diagnostic_item(sym::Option, adt_def.did()) {
|
if cx.tcx.is_diagnostic_item(sym::Option, adt_def.did()) {
|
||||||
("Option", OptionSome, subst.type_at(0))
|
("Option", OptionSome, subst.type_at(0))
|
||||||
} else if cx.tcx.is_diagnostic_item(sym::Result, adt_def.did()) {
|
} else if cx.tcx.is_diagnostic_item(sym::Result, adt_def.did()) {
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_help;
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor};
|
use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor};
|
||||||
use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, YieldSource};
|
use rustc_hir::{Body, Expr, ExprKind, FnDecl, YieldSource};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
@ -66,11 +67,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
|
|||||||
fn_decl: &'tcx FnDecl<'tcx>,
|
fn_decl: &'tcx FnDecl<'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
hir_id: HirId,
|
def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
if !span.from_expansion() && fn_kind.asyncness().is_async() {
|
if !span.from_expansion() && fn_kind.asyncness().is_async() {
|
||||||
let mut visitor = AsyncFnVisitor { cx, found_await: false };
|
let mut visitor = AsyncFnVisitor { cx, found_await: false };
|
||||||
walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), hir_id);
|
walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), def_id);
|
||||||
if !visitor.found_await {
|
if !visitor.found_await {
|
||||||
span_lint_and_help(
|
span_lint_and_help(
|
||||||
cx,
|
cx,
|
||||||
|
@ -11,6 +11,7 @@ use rustc_middle::hir::nested_filter;
|
|||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
|
||||||
@ -312,7 +313,7 @@ impl<'tcx> LateLintPass<'tcx> for Unwrap {
|
|||||||
decl: &'tcx FnDecl<'_>,
|
decl: &'tcx FnDecl<'_>,
|
||||||
body: &'tcx Body<'_>,
|
body: &'tcx Body<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
fn_id: HirId,
|
fn_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
if span.from_expansion() {
|
if span.from_expansion() {
|
||||||
return;
|
return;
|
||||||
|
@ -64,8 +64,8 @@ impl<'tcx> LateLintPass<'tcx> for UnwrapInResult {
|
|||||||
// first check if it's a method or function
|
// first check if it's a method or function
|
||||||
if let hir::ImplItemKind::Fn(ref _signature, _) = impl_item.kind;
|
if let hir::ImplItemKind::Fn(ref _signature, _) = impl_item.kind;
|
||||||
// checking if its return type is `result` or `option`
|
// checking if its return type is `result` or `option`
|
||||||
if is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id()), sym::Result)
|
if is_type_diagnostic_item(cx, return_ty(cx, impl_item.owner_id), sym::Result)
|
||||||
|| is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id()), sym::Option);
|
|| is_type_diagnostic_item(cx, return_ty(cx, impl_item.owner_id), sym::Option);
|
||||||
then {
|
then {
|
||||||
lint_impl_body(cx, impl_item.span, impl_item);
|
lint_impl_body(cx, impl_item.span, impl_item);
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
|
|||||||
.associated_item(impl_item.owner_id)
|
.associated_item(impl_item.owner_id)
|
||||||
.trait_item_def_id
|
.trait_item_def_id
|
||||||
.expect("impl method matches a trait method");
|
.expect("impl method matches a trait method");
|
||||||
let trait_method_sig = cx.tcx.fn_sig(trait_method);
|
let trait_method_sig = cx.tcx.fn_sig(trait_method).subst_identity();
|
||||||
let trait_method_sig = cx.tcx.erase_late_bound_regions(trait_method_sig);
|
let trait_method_sig = cx.tcx.erase_late_bound_regions(trait_method_sig);
|
||||||
|
|
||||||
// `impl_inputs_outputs` is an iterator over the types (`hir::Ty`) declared in the
|
// `impl_inputs_outputs` is an iterator over the types (`hir::Ty`) declared in the
|
||||||
|
@ -215,14 +215,13 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
|
|||||||
cx,
|
cx,
|
||||||
};
|
};
|
||||||
let body_id = cx.tcx.hir().body_owned_by(
|
let body_id = cx.tcx.hir().body_owned_by(
|
||||||
cx.tcx.hir().local_def_id(
|
|
||||||
impl_item_refs
|
impl_item_refs
|
||||||
.iter()
|
.iter()
|
||||||
.find(|iiref| iiref.ident.as_str() == "get_lints")
|
.find(|iiref| iiref.ident.as_str() == "get_lints")
|
||||||
.expect("LintPass needs to implement get_lints")
|
.expect("LintPass needs to implement get_lints")
|
||||||
.id
|
.id
|
||||||
.hir_id(),
|
.owner_id
|
||||||
),
|
.def_id,
|
||||||
);
|
);
|
||||||
collector.visit_expr(cx.tcx.hir().body(body_id).value);
|
collector.visit_expr(cx.tcx.hir().body(body_id).value);
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg:
|
|||||||
&& subs.types().all(|x| matches!(x.peel_refs().kind(), ty::Param(_)))
|
&& subs.types().all(|x| matches!(x.peel_refs().kind(), ty::Param(_)))
|
||||||
{
|
{
|
||||||
// Limit the function to either `(self) -> bool` or `(&self) -> bool`
|
// Limit the function to either `(self) -> bool` or `(&self) -> bool`
|
||||||
match &**cx.tcx.fn_sig(fn_id).skip_binder().inputs_and_output {
|
match &**cx.tcx.fn_sig(fn_id).subst_identity().skip_binder().inputs_and_output {
|
||||||
[arg, res] if !arg.is_mutable_ptr() && arg.peel_refs() == ty && res.is_bool() => NoChange,
|
[arg, res] if !arg.is_mutable_ptr() && arg.peel_refs() == ty && res.is_bool() => NoChange,
|
||||||
_ => Lazy,
|
_ => Lazy,
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#![feature(array_chunks)]
|
#![feature(array_chunks)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(control_flow_enum)]
|
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(lint_reasons)]
|
#![feature(lint_reasons)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
@ -1119,9 +1118,8 @@ pub fn can_move_expr_to_closure<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'
|
|||||||
self.captures.entry(l).and_modify(|e| *e |= cap).or_insert(cap);
|
self.captures.entry(l).and_modify(|e| *e |= cap).or_insert(cap);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ExprKind::Closure { .. } => {
|
ExprKind::Closure(closure) => {
|
||||||
let closure_id = self.cx.tcx.hir().local_def_id(e.hir_id);
|
for capture in self.cx.typeck_results().closure_min_captures_flattened(closure.def_id) {
|
||||||
for capture in self.cx.typeck_results().closure_min_captures_flattened(closure_id) {
|
|
||||||
let local_id = match capture.place.base {
|
let local_id = match capture.place.base {
|
||||||
PlaceBase::Local(id) => id,
|
PlaceBase::Local(id) => id,
|
||||||
PlaceBase::Upvar(var) => var.var_path.hir_id,
|
PlaceBase::Upvar(var) => var.var_path.hir_id,
|
||||||
@ -1379,7 +1377,7 @@ pub fn get_enclosing_loop_or_multi_call_closure<'tcx>(
|
|||||||
.chain(args.iter())
|
.chain(args.iter())
|
||||||
.position(|arg| arg.hir_id == id)?;
|
.position(|arg| arg.hir_id == id)?;
|
||||||
let id = cx.typeck_results().type_dependent_def_id(e.hir_id)?;
|
let id = cx.typeck_results().type_dependent_def_id(e.hir_id)?;
|
||||||
let ty = cx.tcx.fn_sig(id).skip_binder().inputs()[i];
|
let ty = cx.tcx.fn_sig(id).subst_identity().skip_binder().inputs()[i];
|
||||||
ty_is_fn_once_param(cx.tcx, ty, cx.tcx.param_env(id).caller_bounds()).then_some(())
|
ty_is_fn_once_param(cx.tcx, ty, cx.tcx.param_env(id).caller_bounds()).then_some(())
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -1578,16 +1576,14 @@ pub fn is_direct_expn_of(span: Span, name: &str) -> Option<Span> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function to get the return type of a function.
|
/// Convenience function to get the return type of a function.
|
||||||
pub fn return_ty<'tcx>(cx: &LateContext<'tcx>, fn_item: hir::HirId) -> Ty<'tcx> {
|
pub fn return_ty<'tcx>(cx: &LateContext<'tcx>, fn_def_id: hir::OwnerId) -> Ty<'tcx> {
|
||||||
let fn_def_id = cx.tcx.hir().local_def_id(fn_item);
|
let ret_ty = cx.tcx.fn_sig(fn_def_id).subst_identity().output();
|
||||||
let ret_ty = cx.tcx.fn_sig(fn_def_id).output();
|
|
||||||
cx.tcx.erase_late_bound_regions(ret_ty)
|
cx.tcx.erase_late_bound_regions(ret_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function to get the nth argument type of a function.
|
/// Convenience function to get the nth argument type of a function.
|
||||||
pub fn nth_arg<'tcx>(cx: &LateContext<'tcx>, fn_item: hir::HirId, nth: usize) -> Ty<'tcx> {
|
pub fn nth_arg<'tcx>(cx: &LateContext<'tcx>, fn_def_id: hir::OwnerId, nth: usize) -> Ty<'tcx> {
|
||||||
let fn_def_id = cx.tcx.hir().local_def_id(fn_item);
|
let arg = cx.tcx.fn_sig(fn_def_id).subst_identity().input(nth);
|
||||||
let arg = cx.tcx.fn_sig(fn_def_id).input(nth);
|
|
||||||
cx.tcx.erase_late_bound_regions(arg)
|
cx.tcx.erase_late_bound_regions(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ fn is_assert_arg(cx: &LateContext<'_>, expr: &Expr<'_>, assert_expn: ExpnId) ->
|
|||||||
} else {
|
} else {
|
||||||
match cx.tcx.item_name(macro_call.def_id) {
|
match cx.tcx.item_name(macro_call.def_id) {
|
||||||
// `cfg!(debug_assertions)` in `debug_assert!`
|
// `cfg!(debug_assertions)` in `debug_assert!`
|
||||||
sym::cfg => ControlFlow::CONTINUE,
|
sym::cfg => ControlFlow::Continue(()),
|
||||||
// assert!(other_macro!(..))
|
// assert!(other_macro!(..))
|
||||||
_ => ControlFlow::Break(true),
|
_ => ControlFlow::Break(true),
|
||||||
}
|
}
|
||||||
@ -711,8 +711,8 @@ pub struct FormatSpec<'tcx> {
|
|||||||
pub fill: Option<char>,
|
pub fill: Option<char>,
|
||||||
/// Optionally specified alignment.
|
/// Optionally specified alignment.
|
||||||
pub align: Alignment,
|
pub align: Alignment,
|
||||||
/// Packed version of various flags provided, see [`rustc_parse_format::Flag`].
|
/// Whether all flag options are set to default (no flags specified).
|
||||||
pub flags: u32,
|
pub no_flags: bool,
|
||||||
/// Represents either the maximum width or the integer precision.
|
/// Represents either the maximum width or the integer precision.
|
||||||
pub precision: Count<'tcx>,
|
pub precision: Count<'tcx>,
|
||||||
/// The minimum width, will be padded according to `width`/`align`
|
/// The minimum width, will be padded according to `width`/`align`
|
||||||
@ -728,7 +728,7 @@ impl<'tcx> FormatSpec<'tcx> {
|
|||||||
Some(Self {
|
Some(Self {
|
||||||
fill: spec.fill,
|
fill: spec.fill,
|
||||||
align: spec.align,
|
align: spec.align,
|
||||||
flags: spec.flags,
|
no_flags: spec.sign.is_none() && !spec.alternate && !spec.zero_pad && spec.debug_hex.is_none(),
|
||||||
precision: Count::new(
|
precision: Count::new(
|
||||||
FormatParamUsage::Precision,
|
FormatParamUsage::Precision,
|
||||||
spec.precision,
|
spec.precision,
|
||||||
@ -770,10 +770,7 @@ impl<'tcx> FormatSpec<'tcx> {
|
|||||||
/// Has no other formatting specifiers than setting the format trait. returns true for `{}`,
|
/// Has no other formatting specifiers than setting the format trait. returns true for `{}`,
|
||||||
/// `{foo}`, `{:?}`, but false for `{foo:5}`, `{3:.5?}`
|
/// `{foo}`, `{:?}`, but false for `{foo:5}`, `{3:.5?}`
|
||||||
pub fn is_default_for_trait(&self) -> bool {
|
pub fn is_default_for_trait(&self) -> bool {
|
||||||
self.width.is_implied()
|
self.width.is_implied() && self.precision.is_implied() && self.align == Alignment::AlignUnknown && self.no_flags
|
||||||
&& self.precision.is_implied()
|
|
||||||
&& self.align == Alignment::AlignUnknown
|
|
||||||
&& self.flags == 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ impl TypeVisitor<'_> for ContainsRegion {
|
|||||||
type BreakTy = ();
|
type BreakTy = ();
|
||||||
|
|
||||||
fn visit_region(&mut self, _: ty::Region<'_>) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, _: ty::Region<'_>) -> ControlFlow<Self::BreakTy> {
|
||||||
ControlFlow::BREAK
|
ControlFlow::Break(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv)
|
|||||||
// impl trait is gone in MIR, so check the return type manually
|
// impl trait is gone in MIR, so check the return type manually
|
||||||
check_ty(
|
check_ty(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.fn_sig(def_id).output().skip_binder(),
|
tcx.fn_sig(def_id).subst_identity().output().skip_binder(),
|
||||||
body.local_decls.iter().next().unwrap().source_info.span,
|
body.local_decls.iter().next().unwrap().source_info.span,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -240,6 +240,7 @@ fn check_statement<'tcx>(
|
|||||||
| StatementKind::Retag { .. }
|
| StatementKind::Retag { .. }
|
||||||
| StatementKind::AscribeUserType(..)
|
| StatementKind::AscribeUserType(..)
|
||||||
| StatementKind::Coverage(..)
|
| StatementKind::Coverage(..)
|
||||||
|
| StatementKind::ConstEvalCounter
|
||||||
| StatementKind::Nop => Ok(()),
|
| StatementKind::Nop => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -809,7 +809,10 @@ pub struct DerefClosure {
|
|||||||
///
|
///
|
||||||
/// note: this only works on single line immutable closures with exactly one input parameter.
|
/// note: this only works on single line immutable closures with exactly one input parameter.
|
||||||
pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Option<DerefClosure> {
|
pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Option<DerefClosure> {
|
||||||
if let hir::ExprKind::Closure(&Closure { fn_decl, body, .. }) = closure.kind {
|
if let hir::ExprKind::Closure(&Closure {
|
||||||
|
fn_decl, def_id, body, ..
|
||||||
|
}) = closure.kind
|
||||||
|
{
|
||||||
let closure_body = cx.tcx.hir().body(body);
|
let closure_body = cx.tcx.hir().body(body);
|
||||||
// is closure arg a type annotated double reference (i.e.: `|x: &&i32| ...`)
|
// is closure arg a type annotated double reference (i.e.: `|x: &&i32| ...`)
|
||||||
// a type annotation is present if param `kind` is different from `TyKind::Infer`
|
// a type annotation is present if param `kind` is different from `TyKind::Infer`
|
||||||
@ -829,10 +832,8 @@ pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Opti
|
|||||||
applicability: Applicability::MachineApplicable,
|
applicability: Applicability::MachineApplicable,
|
||||||
};
|
};
|
||||||
|
|
||||||
let fn_def_id = cx.tcx.hir().local_def_id(closure.hir_id);
|
|
||||||
let infcx = cx.tcx.infer_ctxt().build();
|
let infcx = cx.tcx.infer_ctxt().build();
|
||||||
ExprUseVisitor::new(&mut visitor, &infcx, fn_def_id, cx.param_env, cx.typeck_results())
|
ExprUseVisitor::new(&mut visitor, &infcx, def_id, cx.param_env, cx.typeck_results()).consume_body(closure_body);
|
||||||
.consume_body(closure_body);
|
|
||||||
|
|
||||||
if !visitor.suggestion_start.is_empty() {
|
if !visitor.suggestion_start.is_empty() {
|
||||||
return Some(DerefClosure {
|
return Some(DerefClosure {
|
||||||
@ -885,7 +886,7 @@ impl<'tcx> DerefDelegate<'_, 'tcx> {
|
|||||||
.cx
|
.cx
|
||||||
.typeck_results()
|
.typeck_results()
|
||||||
.type_dependent_def_id(parent_expr.hir_id)
|
.type_dependent_def_id(parent_expr.hir_id)
|
||||||
.map(|did| self.cx.tcx.fn_sig(did).skip_binder())
|
.map(|did| self.cx.tcx.fn_sig(did).subst_identity().skip_binder())
|
||||||
{
|
{
|
||||||
std::iter::once(receiver)
|
std::iter::once(receiver)
|
||||||
.chain(call_args.iter())
|
.chain(call_args.iter())
|
||||||
|
@ -628,7 +628,7 @@ impl<'tcx> ExprFnSig<'tcx> {
|
|||||||
/// If the expression is function like, get the signature for it.
|
/// If the expression is function like, get the signature for it.
|
||||||
pub fn expr_sig<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option<ExprFnSig<'tcx>> {
|
pub fn expr_sig<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option<ExprFnSig<'tcx>> {
|
||||||
if let Res::Def(DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::AssocFn, id) = path_res(cx, expr) {
|
if let Res::Def(DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::AssocFn, id) = path_res(cx, expr) {
|
||||||
Some(ExprFnSig::Sig(cx.tcx.fn_sig(id), Some(id)))
|
Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).subst_identity(), Some(id)))
|
||||||
} else {
|
} else {
|
||||||
ty_sig(cx, cx.typeck_results().expr_ty_adjusted(expr).peel_refs())
|
ty_sig(cx, cx.typeck_results().expr_ty_adjusted(expr).peel_refs())
|
||||||
}
|
}
|
||||||
@ -646,7 +646,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
|
|||||||
.and_then(|id| cx.tcx.hir().fn_decl_by_hir_id(cx.tcx.hir().local_def_id_to_hir_id(id)));
|
.and_then(|id| cx.tcx.hir().fn_decl_by_hir_id(cx.tcx.hir().local_def_id_to_hir_id(id)));
|
||||||
Some(ExprFnSig::Closure(decl, subs.as_closure().sig()))
|
Some(ExprFnSig::Closure(decl, subs.as_closure().sig()))
|
||||||
},
|
},
|
||||||
ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.bound_fn_sig(id).subst(cx.tcx, subs), Some(id))),
|
ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).subst(cx.tcx, subs), Some(id))),
|
||||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => sig_from_bounds(
|
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => sig_from_bounds(
|
||||||
cx,
|
cx,
|
||||||
ty,
|
ty,
|
||||||
|
@ -392,12 +392,16 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
|
|||||||
.cx
|
.cx
|
||||||
.typeck_results()
|
.typeck_results()
|
||||||
.type_dependent_def_id(e.hir_id)
|
.type_dependent_def_id(e.hir_id)
|
||||||
.map_or(false, |id| self.cx.tcx.fn_sig(id).unsafety() == Unsafety::Unsafe) =>
|
.map_or(false, |id| {
|
||||||
|
self.cx.tcx.fn_sig(id).skip_binder().unsafety() == Unsafety::Unsafe
|
||||||
|
}) =>
|
||||||
{
|
{
|
||||||
self.is_unsafe = true;
|
self.is_unsafe = true;
|
||||||
},
|
},
|
||||||
ExprKind::Call(func, _) => match *self.cx.typeck_results().expr_ty(func).peel_refs().kind() {
|
ExprKind::Call(func, _) => match *self.cx.typeck_results().expr_ty(func).peel_refs().kind() {
|
||||||
ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).unsafety() == Unsafety::Unsafe => self.is_unsafe = true,
|
ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().unsafety() == Unsafety::Unsafe => {
|
||||||
|
self.is_unsafe = true;
|
||||||
|
},
|
||||||
ty::FnPtr(sig) if sig.unsafety() == Unsafety::Unsafe => self.is_unsafe = true,
|
ty::FnPtr(sig) if sig.unsafety() == Unsafety::Unsafe => self.is_unsafe = true,
|
||||||
_ => walk_expr(self, e),
|
_ => walk_expr(self, e),
|
||||||
},
|
},
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2023-01-27"
|
channel = "nightly-2023-02-10"
|
||||||
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
|
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
|
||||||
|
@ -1,12 +1,3 @@
|
|||||||
error: hardcoded path to a diagnostic item
|
|
||||||
--> $DIR/unnecessary_def_path_hardcoded_path.rs:10:36
|
|
||||||
|
|
|
||||||
LL | const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: convert all references to use `sym::Deref`
|
|
||||||
= note: `-D clippy::unnecessary-def-path` implied by `-D warnings`
|
|
||||||
|
|
||||||
error: hardcoded path to a diagnostic item
|
error: hardcoded path to a diagnostic item
|
||||||
--> $DIR/unnecessary_def_path_hardcoded_path.rs:12:43
|
--> $DIR/unnecessary_def_path_hardcoded_path.rs:12:43
|
||||||
|
|
|
|
||||||
@ -14,6 +5,15 @@ LL | const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref",
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: convert all references to use `sym::deref_method`
|
= help: convert all references to use `sym::deref_method`
|
||||||
|
= note: `-D clippy::unnecessary-def-path` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: hardcoded path to a diagnostic item
|
||||||
|
--> $DIR/unnecessary_def_path_hardcoded_path.rs:10:36
|
||||||
|
|
|
||||||
|
LL | const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: convert all references to use `sym::Deref`
|
||||||
|
|
||||||
error: hardcoded path to a language item
|
error: hardcoded path to a language item
|
||||||
--> $DIR/unnecessary_def_path_hardcoded_path.rs:11:40
|
--> $DIR/unnecessary_def_path_hardcoded_path.rs:11:40
|
||||||
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
|||||||
--> $DIR/track-diagnostics.rs:LL:CC
|
--> $DIR/track-diagnostics.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | const S: A = B;
|
LL | const S: A = B;
|
||||||
| ^ expected struct `A`, found struct `B`
|
| ^ expected `A`, found `B`
|
||||||
-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:LL:CC
|
-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:LL:CC
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
Loading…
Reference in New Issue
Block a user