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

Rustup

r? `@ghost`

changelog: none
This commit is contained in:
bors 2023-02-10 10:38:32 +00:00
commit a7fecd6911
70 changed files with 286 additions and 245 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<'_>,
matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })) _: FnKind<'_>,
} else { decl: &FnDecl<'_>,
false _: &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(_), .. }))
} else {
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,

View File

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

View File

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

View File

@ -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,17 +102,18 @@ 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 cx.tcx.is_diagnostic_item(sym::Option, adt_def.did()) { if let ty::Adt(adt_def, subst) = return_ty(cx, hir_id.expect_owner()).kind() {
("Option", OptionSome, subst.type_at(0)) if cx.tcx.is_diagnostic_item(sym::Option, adt_def.did()) {
} else if cx.tcx.is_diagnostic_item(sym::Result, adt_def.did()) { ("Option", OptionSome, subst.type_at(0))
("Result", ResultOk, subst.type_at(0)) } else if cx.tcx.is_diagnostic_item(sym::Result, adt_def.did()) {
("Result", ResultOk, subst.type_at(0))
} else {
return;
}
} else { } else {
return; return;
} };
} else {
return;
};
// Check if all return expression respect the following condition and collect them. // Check if all return expression respect the following condition and collect them.
let mut suggs = Vec::new(); let mut suggs = Vec::new();

View File

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

View File

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

View File

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

View File

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

View File

@ -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 .owner_id
.hir_id(), .def_id,
),
); );
collector.visit_expr(cx.tcx.hir().body(body_id).value); collector.visit_expr(cx.tcx.hir().body(body_id).value);
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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