1
Fork 0

refactor(rustc_middle): Substs -> GenericArg

This commit is contained in:
Mahdi Dibaiee 2023-07-11 22:35:29 +01:00
parent 660ef4ffe8
commit fdb2e363d3
94 changed files with 307 additions and 307 deletions

View file

@ -47,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
&& let result_type_with_refs = cx.typeck_results().expr_ty(recv) && let result_type_with_refs = cx.typeck_results().expr_ty(recv)
&& let result_type = result_type_with_refs.peel_refs() && let result_type = result_type_with_refs.peel_refs()
&& is_type_diagnostic_item(cx, result_type, sym::Result) && is_type_diagnostic_item(cx, result_type, sym::Result)
&& let ty::Adt(_, substs) = result_type.kind() && let ty::Adt(_, args) = result_type.kind()
{ {
if !is_copy(cx, result_type) { if !is_copy(cx, result_type) {
if result_type_with_refs != result_type { if result_type_with_refs != result_type {
@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
let semicolon = if is_expr_final_block_expr(cx.tcx, e) {";"} else {""}; let semicolon = if is_expr_final_block_expr(cx.tcx, e) {";"} else {""};
let mut app = Applicability::MachineApplicable; let mut app = Applicability::MachineApplicable;
match method_segment.ident.as_str() { match method_segment.ident.as_str() {
"is_ok" if type_suitable_to_unwrap(cx, substs.type_at(1)) => { "is_ok" if type_suitable_to_unwrap(cx, args.type_at(1)) => {
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
ASSERTIONS_ON_RESULT_STATES, ASSERTIONS_ON_RESULT_STATES,
@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
app, app,
); );
} }
"is_err" if type_suitable_to_unwrap(cx, substs.type_at(0)) => { "is_err" if type_suitable_to_unwrap(cx, args.type_at(0)) => {
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
ASSERTIONS_ON_RESULT_STATES, ASSERTIONS_ON_RESULT_STATES,

View file

@ -61,7 +61,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -
) )
}) })
.map_or(false, |assoc_item| { .map_or(false, |assoc_item| {
let proj = Ty::new_projection(cx.tcx,assoc_item.def_id, cx.tcx.mk_substs_trait(ty, [])); let proj = Ty::new_projection(cx.tcx,assoc_item.def_id, cx.tcx.mk_args_trait(ty, []));
let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj); let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj);
nty.is_bool() nty.is_bool()

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).subst_identity() && let as_ptr_sig = cx.tcx.fn_sig(as_ptr_did).instantiate_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

@ -66,7 +66,7 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
if matches!(name.ident.as_str(), "read_unaligned" | "write_unaligned") if matches!(name.ident.as_str(), "read_unaligned" | "write_unaligned")
&& let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id) && let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id)
&& let Some(def_id) = cx.tcx.impl_of_method(def_id) && let Some(def_id) = cx.tcx.impl_of_method(def_id)
&& cx.tcx.type_of(def_id).subst_identity().is_unsafe_ptr() && cx.tcx.type_of(def_id).instantiate_identity().is_unsafe_ptr()
{ {
true true
} else { } else {

View file

@ -43,7 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for CopyIterator {
of_trait: Some(ref trait_ref), of_trait: Some(ref trait_ref),
.. ..
}) = item.kind; }) = item.kind;
let ty = cx.tcx.type_of(item.owner_id).subst_identity(); let ty = cx.tcx.type_of(item.owner_id).instantiate_identity();
if is_copy(cx, ty); if is_copy(cx, ty);
if let Some(trait_id) = trait_ref.trait_def_id(); if let Some(trait_id) = trait_ref.trait_def_id();
if cx.tcx.is_diagnostic_item(sym::Iterator, trait_id); if cx.tcx.is_diagnostic_item(sym::Iterator, trait_id);

View file

@ -150,7 +150,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
.fields .fields
.iter() .iter()
.all(|field| { .all(|field| {
is_copy(cx, cx.tcx.type_of(field.did).subst_identity()) is_copy(cx, cx.tcx.type_of(field.did).instantiate_identity())
}); });
if !has_drop(cx, binding_type) || all_fields_are_copy; if !has_drop(cx, binding_type) || all_fields_are_copy;
then { then {
@ -219,11 +219,11 @@ impl<'tcx> LateLintPass<'tcx> for Default {
// give correct suggestion if generics are involved (see #6944) // give correct suggestion if generics are involved (see #6944)
let binding_type = if_chain! { let binding_type = if_chain! {
if let ty::Adt(adt_def, substs) = binding_type.kind(); if let ty::Adt(adt_def, args) = binding_type.kind();
if !substs.is_empty(); if !args.is_empty();
then { then {
let adt_def_ty_name = cx.tcx.item_name(adt_def.did()); let adt_def_ty_name = cx.tcx.item_name(adt_def.did());
let generic_args = substs.iter().collect::<Vec<_>>(); let generic_args = args.iter().collect::<Vec<_>>();
let tys_str = generic_args let tys_str = generic_args
.iter() .iter()
.map(ToString::to_string) .map(ToString::to_string)

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).subst_identity().skip_binder(); let fn_sig = self.cx.tcx.fn_sig(def_id).instantiate_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);
@ -167,7 +167,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
.iter() .iter()
.find_map(|f_def| { .find_map(|f_def| {
if f_def.ident(self.cx.tcx) == field.ident if f_def.ident(self.cx.tcx) == field.ident
{ Some(self.cx.tcx.type_of(f_def.did).subst_identity()) } { Some(self.cx.tcx.type_of(f_def.did).instantiate_identity()) }
else { None } else { None }
}); });
self.ty_bounds.push(bound.into()); self.ty_bounds.push(bound.into());
@ -213,9 +213,9 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
fn fn_sig_opt<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<PolyFnSig<'tcx>> { fn fn_sig_opt<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<PolyFnSig<'tcx>> {
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 args, this may result in FNs.
match node_ty.kind() { match node_ty.kind() {
ty::FnDef(def_id, _) => Some(cx.tcx.fn_sig(*def_id).subst_identity()), ty::FnDef(def_id, _) => Some(cx.tcx.fn_sig(*def_id).instantiate_identity()),
ty::FnPtr(fn_sig) => Some(*fn_sig), ty::FnPtr(fn_sig) => Some(*fn_sig),
_ => None, _ => None,
} }

View file

@ -739,7 +739,7 @@ fn walk_parents<'tcx>(
span, span,
.. ..
}) if span.ctxt() == ctxt => { }) if span.ctxt() == ctxt => {
let ty = cx.tcx.type_of(owner_id.def_id).subst_identity(); let ty = cx.tcx.type_of(owner_id.def_id).instantiate_identity();
Some(ty_auto_deref_stability(cx.tcx, cx.param_env, ty, precedence).position_for_result(cx)) Some(ty_auto_deref_stability(cx.tcx, cx.param_env, ty, precedence).position_for_result(cx))
}, },
@ -763,7 +763,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).subst_identity().output()); .erase_late_bound_regions(cx.tcx.fn_sig(owner_id).instantiate_identity().output());
Some(ty_auto_deref_stability(cx.tcx, cx.param_env, output, precedence).position_for_result(cx)) Some(ty_auto_deref_stability(cx.tcx, cx.param_env, output, precedence).position_for_result(cx))
}, },
@ -785,7 +785,7 @@ fn walk_parents<'tcx>(
cx.tcx, cx.tcx,
// Use the param_env of the target type. // Use the param_env of the target type.
cx.tcx.param_env(adt.did()), cx.tcx.param_env(adt.did()),
cx.tcx.type_of(field_def.did).subst_identity(), cx.tcx.type_of(field_def.did).instantiate_identity(),
precedence, precedence,
) )
.position_for_arg() .position_for_arg()
@ -808,7 +808,7 @@ fn walk_parents<'tcx>(
} else { } else {
let output = cx let output = cx
.tcx .tcx
.erase_late_bound_regions(cx.tcx.fn_sig(owner_id).subst_identity().output()); .erase_late_bound_regions(cx.tcx.fn_sig(owner_id).instantiate_identity().output());
ty_auto_deref_stability(cx.tcx, cx.param_env, output, precedence).position_for_result(cx) ty_auto_deref_stability(cx.tcx, cx.param_env, output, precedence).position_for_result(cx)
}, },
) )
@ -879,9 +879,9 @@ fn walk_parents<'tcx>(
&& let ty::Ref(_, sub_ty, _) = *arg_ty.kind() && let ty::Ref(_, sub_ty, _) = *arg_ty.kind()
&& let subs = cx && let subs = cx
.typeck_results() .typeck_results()
.node_substs_opt(parent.hir_id).map(|subs| &subs[1..]).unwrap_or_default() .node_args_opt(parent.hir_id).map(|subs| &subs[1..]).unwrap_or_default()
&& let impl_ty = if cx.tcx.fn_sig(fn_id) && let impl_ty = if cx.tcx.fn_sig(fn_id)
.subst_identity() .instantiate_identity()
.skip_binder() .skip_binder()
.inputs()[0].is_ref() .inputs()[0].is_ref()
{ {
@ -905,7 +905,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(fn_id).subst_identity().input(i + 1); let ty = cx.tcx.fn_sig(fn_id).instantiate_identity().input(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 if e.hir_id == child_id
@ -1124,10 +1124,10 @@ 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).subst_identity().skip_binder(); let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_binder();
let substs_with_expr_ty = cx let args_with_expr_ty = cx
.typeck_results() .typeck_results()
.node_substs(if let ExprKind::Call(callee, _) = parent.kind { .node_args(if let ExprKind::Call(callee, _) = parent.kind {
callee.hir_id callee.hir_id
} else { } else {
parent.hir_id parent.hir_id
@ -1181,9 +1181,9 @@ fn needless_borrow_impl_arg_position<'tcx>(
return Position::Other(precedence); return Position::Other(precedence);
} }
// `substs_with_referent_ty` can be constructed outside of `check_referent` because the same // `args_with_referent_ty` can be constructed outside of `check_referent` because the same
// elements are modified each time `check_referent` is called. // elements are modified each time `check_referent` is called.
let mut substs_with_referent_ty = substs_with_expr_ty.to_vec(); let mut args_with_referent_ty = args_with_expr_ty.to_vec();
let mut check_reference_and_referent = |reference, referent| { let mut check_reference_and_referent = |reference, referent| {
let referent_ty = cx.typeck_results().expr_ty(referent); let referent_ty = cx.typeck_results().expr_ty(referent);
@ -1207,7 +1207,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
fn_sig, fn_sig,
arg_index, arg_index,
&projection_predicates, &projection_predicates,
&mut substs_with_referent_ty, &mut args_with_referent_ty,
) { ) {
return false; return false;
} }
@ -1216,14 +1216,14 @@ fn needless_borrow_impl_arg_position<'tcx>(
if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
&& cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id) && cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id)
&& let ty::Param(param_ty) = trait_predicate.self_ty().kind() && let ty::Param(param_ty) = trait_predicate.self_ty().kind()
&& let GenericArgKind::Type(ty) = substs_with_referent_ty[param_ty.index as usize].unpack() && let GenericArgKind::Type(ty) = args_with_referent_ty[param_ty.index as usize].unpack()
&& ty.is_array() && ty.is_array()
&& !msrv.meets(msrvs::ARRAY_INTO_ITERATOR) && !msrv.meets(msrvs::ARRAY_INTO_ITERATOR)
{ {
return false; return false;
} }
let predicate = EarlyBinder::bind(predicate).subst(cx.tcx, &substs_with_referent_ty); let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty);
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate); let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
let infcx = cx.tcx.infer_ctxt().build(); let infcx = cx.tcx.infer_ctxt().build();
infcx.predicate_must_hold_modulo_regions(&obligation) infcx.predicate_must_hold_modulo_regions(&obligation)
@ -1252,7 +1252,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).subst_identity().skip_binder().inputs()[0]; let self_ty = cx.tcx.fn_sig(assoc_item.def_id).instantiate_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
@ -1323,7 +1323,7 @@ fn referent_used_exactly_once<'tcx>(
} }
} }
// Iteratively replaces `param_ty` with `new_ty` in `substs`, and similarly for each resulting // Iteratively replaces `param_ty` with `new_ty` in `args`, and similarly for each resulting
// projected type that is a type parameter. Returns `false` if replacing the types would have an // projected type that is a type parameter. Returns `false` if replacing the types would have an
// effect on the function signature beyond substituting `new_ty` for `param_ty`. // effect on the function signature beyond substituting `new_ty` for `param_ty`.
// See: https://github.com/rust-lang/rust-clippy/pull/9136#discussion_r927212757 // See: https://github.com/rust-lang/rust-clippy/pull/9136#discussion_r927212757
@ -1334,11 +1334,11 @@ fn replace_types<'tcx>(
fn_sig: FnSig<'tcx>, fn_sig: FnSig<'tcx>,
arg_index: usize, arg_index: usize,
projection_predicates: &[ProjectionPredicate<'tcx>], projection_predicates: &[ProjectionPredicate<'tcx>],
substs: &mut [ty::GenericArg<'tcx>], args: &mut [ty::GenericArg<'tcx>],
) -> bool { ) -> bool {
let mut replaced = BitSet::new_empty(substs.len()); let mut replaced = BitSet::new_empty(args.len());
let mut deque = VecDeque::with_capacity(substs.len()); let mut deque = VecDeque::with_capacity(args.len());
deque.push_back((param_ty, new_ty)); deque.push_back((param_ty, new_ty));
while let Some((param_ty, new_ty)) = deque.pop_front() { while let Some((param_ty, new_ty)) = deque.pop_front() {
@ -1352,7 +1352,7 @@ fn replace_types<'tcx>(
return false; return false;
} }
substs[param_ty.index as usize] = ty::GenericArg::from(new_ty); args[param_ty.index as usize] = ty::GenericArg::from(new_ty);
// The `replaced.insert(...)` check provides some protection against infinite loops. // The `replaced.insert(...)` check provides some protection against infinite loops.
if replaced.insert(param_ty.index) { if replaced.insert(param_ty.index) {
@ -1367,7 +1367,7 @@ fn replace_types<'tcx>(
)); ));
if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection) if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection)
&& substs[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty) && args[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty)
{ {
deque.push_back((*term_param_ty, projected_ty)); deque.push_back((*term_param_ty, projected_ty));
} }
@ -1442,7 +1442,7 @@ fn ty_auto_deref_stability<'tcx>(
ty::Adt(..) if ty.has_placeholders() || ty.has_opaque_types() => { ty::Adt(..) if ty.has_placeholders() || ty.has_opaque_types() => {
Position::ReborrowStable(precedence).into() Position::ReborrowStable(precedence).into()
}, },
ty::Adt(_, substs) if substs.has_non_region_param() => { ty::Adt(_, args) if args.has_non_region_param() => {
TyPosition::new_deref_stable_for_result(precedence, ty) TyPosition::new_deref_stable_for_result(precedence, ty)
}, },
ty::Bool ty::Bool

View file

@ -10,7 +10,7 @@ use rustc_hir::{
}; };
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::{Adjust, PointerCoercion}; use rustc_middle::ty::adjustment::{Adjust, PointerCoercion};
use rustc_middle::ty::{self, Adt, AdtDef, SubstsRef, Ty, TypeckResults}; use rustc_middle::ty::{self, Adt, AdtDef, GenericArgsRef, Ty, TypeckResults};
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::sym; use rustc_span::sym;
@ -80,7 +80,7 @@ fn is_path_self(e: &Expr<'_>) -> bool {
fn contains_trait_object(ty: Ty<'_>) -> bool { fn contains_trait_object(ty: Ty<'_>) -> bool {
match ty.kind() { match ty.kind() {
ty::Ref(_, ty, _) => contains_trait_object(*ty), ty::Ref(_, ty, _) => contains_trait_object(*ty),
ty::Adt(def, substs) => def.is_box() && substs[0].as_type().map_or(false, contains_trait_object), ty::Adt(def, args) => def.is_box() && args[0].as_type().map_or(false, contains_trait_object),
ty::Dynamic(..) => true, ty::Dynamic(..) => true,
_ => false, _ => false,
} }
@ -92,18 +92,18 @@ fn check_struct<'tcx>(
self_ty: &hir::Ty<'_>, self_ty: &hir::Ty<'_>,
func_expr: &Expr<'_>, func_expr: &Expr<'_>,
adt_def: AdtDef<'_>, adt_def: AdtDef<'_>,
substs: SubstsRef<'_>, ty_args: GenericArgsRef<'_>,
typeck_results: &'tcx TypeckResults<'tcx>, typeck_results: &'tcx TypeckResults<'tcx>,
) { ) {
if let TyKind::Path(QPath::Resolved(_, p)) = self_ty.kind { if let TyKind::Path(QPath::Resolved(_, p)) = self_ty.kind {
if let Some(PathSegment { args, .. }) = p.segments.last() { if let Some(PathSegment { args, .. }) = p.segments.last() {
let args = args.map(|a| a.args).unwrap_or(&[]); let args = args.map(|a| a.args).unwrap_or(&[]);
// substs contains the generic parameters of the type declaration, while args contains the arguments // ty_args contains the generic parameters of the type declaration, while args contains the arguments
// used at instantiation time. If both len are not equal, it means that some parameters were not // used at instantiation time. If both len are not equal, it means that some parameters were not
// provided (which means that the default values were used); in this case we will not risk // provided (which means that the default values were used); in this case we will not risk
// suggesting too broad a rewrite. We won't either if any argument is a type or a const. // suggesting too broad a rewrite. We won't either if any argument is a type or a const.
if substs.len() != args.len() || args.iter().any(|arg| !matches!(arg, GenericArg::Lifetime(_))) { if ty_args.len() != args.len() || args.iter().any(|arg| !matches!(arg, GenericArg::Lifetime(_))) {
return; return;
} }
} }
@ -214,7 +214,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
if let Some(Node::ImplItem(impl_item)) = cx.tcx.hir().find(impl_item_hir); if let Some(Node::ImplItem(impl_item)) = cx.tcx.hir().find(impl_item_hir);
if let ImplItemKind::Fn(_, b) = &impl_item.kind; if let ImplItemKind::Fn(_, b) = &impl_item.kind;
if let Body { value: func_expr, .. } = cx.tcx.hir().body(*b); if let Body { value: func_expr, .. } = cx.tcx.hir().body(*b);
if let &Adt(adt_def, substs) = cx.tcx.type_of(item.owner_id).subst_identity().kind(); if let &Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind();
if let attrs = cx.tcx.hir().attrs(item.hir_id()); if let attrs = cx.tcx.hir().attrs(item.hir_id());
if !attrs.iter().any(|attr| attr.doc_str().is_some()); if !attrs.iter().any(|attr| attr.doc_str().is_some());
if let child_attrs = cx.tcx.hir().attrs(impl_item_hir); if let child_attrs = cx.tcx.hir().attrs(impl_item_hir);
@ -222,7 +222,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
then { then {
if adt_def.is_struct() { if adt_def.is_struct() {
check_struct(cx, item, self_ty, func_expr, adt_def, substs, cx.tcx.typeck_body(*b)); check_struct(cx, item, self_ty, func_expr, adt_def, args, cx.tcx.typeck_body(*b));
} else if adt_def.is_enum() && self.msrv.meets(msrvs::DEFAULT_ENUM_ATTRIBUTE) { } else if adt_def.is_enum() && self.msrv.meets(msrvs::DEFAULT_ENUM_ATTRIBUTE) {
check_enum(cx, item, func_expr, adt_def); check_enum(cx, item, func_expr, adt_def);
} }

View file

@ -211,7 +211,7 @@ impl<'tcx> LateLintPass<'tcx> for Derive {
.. ..
}) = item.kind }) = item.kind
{ {
let ty = cx.tcx.type_of(item.owner_id).subst_identity(); let ty = cx.tcx.type_of(item.owner_id).instantiate_identity();
let is_automatically_derived = cx.tcx.has_attr(item.owner_id, sym::automatically_derived); let is_automatically_derived = cx.tcx.has_attr(item.owner_id, sym::automatically_derived);
check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived); check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived);
@ -252,7 +252,7 @@ fn check_hash_peq<'tcx>(
// Only care about `impl PartialEq<Foo> for Foo` // Only care about `impl PartialEq<Foo> for Foo`
// For `impl PartialEq<B> for A, input_types is [A, B] // For `impl PartialEq<B> for A, input_types is [A, B]
if trait_ref.subst_identity().substs.type_at(1) == ty { if trait_ref.instantiate_identity().args.type_at(1) == ty {
span_lint_and_then( span_lint_and_then(
cx, cx,
DERIVED_HASH_WITH_MANUAL_EQ, DERIVED_HASH_WITH_MANUAL_EQ,
@ -300,7 +300,7 @@ fn check_ord_partial_ord<'tcx>(
// Only care about `impl PartialOrd<Foo> for Foo` // Only care about `impl PartialOrd<Foo> for Foo`
// For `impl PartialOrd<B> for A, input_types is [A, B] // For `impl PartialOrd<B> for A, input_types is [A, B]
if trait_ref.subst_identity().substs.type_at(1) == ty { if trait_ref.instantiate_identity().args.type_at(1) == ty {
let mess = if partial_ord_is_automatically_derived { let mess = if partial_ord_is_automatically_derived {
"you are implementing `Ord` explicitly but have derived `PartialOrd`" "you are implementing `Ord` explicitly but have derived `PartialOrd`"
} else { } else {
@ -347,7 +347,7 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h
let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(&copy_id).map_or(false, |impls| { let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(&copy_id).map_or(false, |impls| {
impls impls
.iter() .iter()
.any(|&id| matches!(cx.tcx.type_of(id).subst_identity().kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did())) .any(|&id| matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did()))
}); });
if !has_copy_impl { if !has_copy_impl {
return; return;
@ -464,7 +464,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
/// Implementation of the `DERIVE_PARTIAL_EQ_WITHOUT_EQ` lint. /// Implementation of the `DERIVE_PARTIAL_EQ_WITHOUT_EQ` lint.
fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) { fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) {
if_chain! { if_chain! {
if let ty::Adt(adt, substs) = ty.kind(); if let ty::Adt(adt, args) = ty.kind();
if cx.tcx.visibility(adt.did()).is_public(); if cx.tcx.visibility(adt.did()).is_public();
if let Some(eq_trait_def_id) = cx.tcx.get_diagnostic_item(sym::Eq); if let Some(eq_trait_def_id) = cx.tcx.get_diagnostic_item(sym::Eq);
if let Some(def_id) = trait_ref.trait_def_id(); if let Some(def_id) = trait_ref.trait_def_id();
@ -474,7 +474,7 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
// If all of our fields implement `Eq`, we can implement `Eq` too // If all of our fields implement `Eq`, we can implement `Eq` too
if adt if adt
.all_fields() .all_fields()
.map(|f| f.ty(cx.tcx, substs)) .map(|f| f.ty(cx.tcx, args))
.all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, [])); .all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, []));
then { then {
span_lint_and_sugg( span_lint_and_sugg(

View file

@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for EmptyEnum {
} }
if let ItemKind::Enum(..) = item.kind { if let ItemKind::Enum(..) = item.kind {
let ty = cx.tcx.type_of(item.owner_id).subst_identity(); let ty = cx.tcx.type_of(item.owner_id).instantiate_identity();
let adt = ty.ty_adt_def().expect("already checked whether this is an enum"); let adt = ty.ty_adt_def().expect("already checked whether this is an enum");
if adt.variants().is_empty() { if adt.variants().is_empty() {
span_lint_and_help( span_lint_and_help(

View file

@ -45,7 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant {
for var in def.variants { for var in def.variants {
if let Some(anon_const) = &var.disr_expr { if let Some(anon_const) = &var.disr_expr {
let def_id = cx.tcx.hir().body_owner_def_id(anon_const.body); let def_id = cx.tcx.hir().body_owner_def_id(anon_const.body);
let mut ty = cx.tcx.type_of(def_id.to_def_id()).subst_identity(); let mut ty = cx.tcx.type_of(def_id.to_def_id()).instantiate_identity();
let constant = cx let constant = cx
.tcx .tcx
.const_eval_poly(def_id.to_def_id()) .const_eval_poly(def_id.to_def_id())

View file

@ -11,7 +11,7 @@ use rustc_hir::{Closure, Expr, ExprKind, Param, PatKind, Unsafety};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
use rustc_middle::ty::binding::BindingMode; use rustc_middle::ty::binding::BindingMode;
use rustc_middle::ty::{self, EarlyBinder, SubstsRef, Ty, TypeVisitableExt}; use rustc_middle::ty::{self, EarlyBinder, GenericArgsRef, Ty, TypeVisitableExt};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
@ -108,18 +108,18 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
if check_inputs(cx, body.params, None, args); if check_inputs(cx, body.params, None, args);
let callee_ty = cx.typeck_results().expr_ty_adjusted(callee); let callee_ty = cx.typeck_results().expr_ty_adjusted(callee);
let call_ty = cx.typeck_results().type_dependent_def_id(body.value.hir_id) let call_ty = cx.typeck_results().type_dependent_def_id(body.value.hir_id)
.map_or(callee_ty, |id| cx.tcx.type_of(id).subst_identity()); .map_or(callee_ty, |id| cx.tcx.type_of(id).instantiate_identity());
if check_sig(cx, closure_ty, call_ty); if check_sig(cx, closure_ty, call_ty);
let substs = cx.typeck_results().node_substs(callee.hir_id); let args = cx.typeck_results().node_args(callee.hir_id);
// This fixes some false positives that I don't entirely understand // This fixes some false positives that I don't entirely understand
if substs.is_empty() || !cx.typeck_results().expr_ty(expr).has_late_bound_regions(); if args.is_empty() || !cx.typeck_results().expr_ty(expr).has_late_bound_regions();
// A type param function ref like `T::f` is not 'static, however // A type param function ref like `T::f` is not 'static, however
// it is if cast like `T::f as fn()`. This seems like a rustc bug. // it is if cast like `T::f as fn()`. This seems like a rustc bug.
if !substs.types().any(|t| matches!(t.kind(), ty::Param(_))); if !args.types().any(|t| matches!(t.kind(), ty::Param(_)));
let callee_ty_unadjusted = cx.typeck_results().expr_ty(callee).peel_refs(); let callee_ty_unadjusted = cx.typeck_results().expr_ty(callee).peel_refs();
if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Arc); if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Arc);
if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Rc); if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Rc);
if let ty::Closure(_, substs) = *closure_ty.kind(); if let ty::Closure(_, args) = *closure_ty.kind();
// Don't lint if this is an inclusive range expression. // Don't lint if this is an inclusive range expression.
// They desugar to a call to `RangeInclusiveNew` which would have odd suggestions. (#10684) // They desugar to a call to `RangeInclusiveNew` which would have odd suggestions. (#10684)
if !matches!(higher::Range::hir(body.value), Some(higher::Range { if !matches!(higher::Range::hir(body.value), Some(higher::Range {
@ -131,7 +131,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| { span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| {
if let Some(mut snippet) = snippet_opt(cx, callee.span) { if let Some(mut snippet) = snippet_opt(cx, callee.span) {
if let Some(fn_mut_id) = cx.tcx.lang_items().fn_mut_trait() if let Some(fn_mut_id) = cx.tcx.lang_items().fn_mut_trait()
&& let args = cx.tcx.erase_late_bound_regions(substs.as_closure().sig()).inputs() && let args = cx.tcx.erase_late_bound_regions(args.as_closure().sig()).inputs()
&& implements_trait( && implements_trait(
cx, cx,
callee_ty.peel_refs(), callee_ty.peel_refs(),
@ -160,12 +160,12 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
if let ExprKind::MethodCall(path, receiver, args, _) = body.value.kind; if let ExprKind::MethodCall(path, receiver, args, _) = body.value.kind;
if check_inputs(cx, body.params, Some(receiver), args); if check_inputs(cx, body.params, Some(receiver), args);
let method_def_id = cx.typeck_results().type_dependent_def_id(body.value.hir_id).unwrap(); let method_def_id = cx.typeck_results().type_dependent_def_id(body.value.hir_id).unwrap();
let substs = cx.typeck_results().node_substs(body.value.hir_id); let args = cx.typeck_results().node_args(body.value.hir_id);
let call_ty = cx.tcx.type_of(method_def_id).subst(cx.tcx, substs); let call_ty = cx.tcx.type_of(method_def_id).instantiate(cx.tcx, args);
if check_sig(cx, closure_ty, call_ty); if check_sig(cx, closure_ty, call_ty);
then { then {
span_lint_and_then(cx, REDUNDANT_CLOSURE_FOR_METHOD_CALLS, expr.span, "redundant closure", |diag| { span_lint_and_then(cx, REDUNDANT_CLOSURE_FOR_METHOD_CALLS, expr.span, "redundant closure", |diag| {
let name = get_ufcs_type_name(cx, method_def_id, substs); let name = get_ufcs_type_name(cx, method_def_id, args);
diag.span_suggestion( diag.span_suggestion(
expr.span, expr.span,
"replace the closure with the method itself", "replace the closure with the method itself",
@ -228,14 +228,14 @@ fn check_sig<'tcx>(cx: &LateContext<'tcx>, closure_ty: Ty<'tcx>, call_ty: Ty<'tc
if !closure_ty.has_late_bound_regions() { if !closure_ty.has_late_bound_regions() {
return true; return true;
} }
let ty::Closure(_, substs) = closure_ty.kind() else { let ty::Closure(_, args) = closure_ty.kind() else {
return false; return false;
}; };
let closure_sig = cx.tcx.signature_unclosure(substs.as_closure().sig(), Unsafety::Normal); let closure_sig = cx.tcx.signature_unclosure(args.as_closure().sig(), Unsafety::Normal);
cx.tcx.erase_late_bound_regions(closure_sig) == cx.tcx.erase_late_bound_regions(call_sig) cx.tcx.erase_late_bound_regions(closure_sig) == cx.tcx.erase_late_bound_regions(call_sig)
} }
fn get_ufcs_type_name<'tcx>(cx: &LateContext<'tcx>, method_def_id: DefId, substs: SubstsRef<'tcx>) -> String { fn get_ufcs_type_name<'tcx>(cx: &LateContext<'tcx>, method_def_id: DefId, args: GenericArgsRef<'tcx>) -> String {
let assoc_item = cx.tcx.associated_item(method_def_id); let assoc_item = cx.tcx.associated_item(method_def_id);
let def_id = assoc_item.container_id(cx.tcx); let def_id = assoc_item.container_id(cx.tcx);
match assoc_item.container { match assoc_item.container {
@ -251,7 +251,7 @@ fn get_ufcs_type_name<'tcx>(cx: &LateContext<'tcx>, method_def_id: DefId, substs
| ty::Ref(..) | ty::Ref(..)
| ty::Slice(_) | ty::Slice(_)
| ty::Tuple(_) => { | ty::Tuple(_) => {
format!("<{}>", EarlyBinder::bind(ty).subst(cx.tcx, substs)) format!("<{}>", EarlyBinder::bind(ty).instantiate(cx.tcx, args))
}, },
_ => ty.to_string(), _ => ty.to_string(),
} }

View file

@ -76,9 +76,9 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto {
&& let Some(into_trait_seg) = hir_trait_ref.path.segments.last() && let Some(into_trait_seg) = hir_trait_ref.path.segments.last()
// `impl Into<target_ty> for self_ty` // `impl Into<target_ty> for self_ty`
&& let Some(GenericArgs { args: [GenericArg::Type(target_ty)], .. }) = into_trait_seg.args && let Some(GenericArgs { args: [GenericArg::Type(target_ty)], .. }) = into_trait_seg.args
&& let Some(middle_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(ty::EarlyBinder::subst_identity) && let Some(middle_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(ty::EarlyBinder::instantiate_identity)
&& cx.tcx.is_diagnostic_item(sym::Into, middle_trait_ref.def_id) && cx.tcx.is_diagnostic_item(sym::Into, middle_trait_ref.def_id)
&& !matches!(middle_trait_ref.substs.type_at(1).kind(), ty::Alias(ty::Opaque, _)) && !matches!(middle_trait_ref.args.type_at(1).kind(), ty::Alias(ty::Opaque, _))
{ {
span_lint_and_then( span_lint_and_then(
cx, cx,

View file

@ -198,14 +198,14 @@ fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, tys: &mut DefIdSet)
match *ty.kind() { match *ty.kind() {
// primitive types are never mutable // primitive types are never mutable
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false, ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false,
ty::Adt(adt, substs) => { ty::Adt(adt, args) => {
tys.insert(adt.did()) && !ty.is_freeze(cx.tcx, cx.param_env) tys.insert(adt.did()) && !ty.is_freeze(cx.tcx, cx.param_env)
|| KNOWN_WRAPPER_TYS || KNOWN_WRAPPER_TYS
.iter() .iter()
.any(|&sym| cx.tcx.is_diagnostic_item(sym, adt.did())) .any(|&sym| cx.tcx.is_diagnostic_item(sym, adt.did()))
&& substs.types().any(|ty| is_mutable_ty(cx, ty, tys)) && args.types().any(|ty| is_mutable_ty(cx, ty, tys))
}, },
ty::Tuple(substs) => substs.iter().any(|ty| is_mutable_ty(cx, ty, tys)), ty::Tuple(args) => args.iter().any(|ty| is_mutable_ty(cx, ty, tys)),
ty::Array(ty, _) | ty::Slice(ty) => is_mutable_ty(cx, ty, tys), ty::Array(ty, _) | ty::Slice(ty) => is_mutable_ty(cx, ty, tys),
ty::RawPtr(ty::TypeAndMut { ty, mutbl }) | ty::Ref(_, ty, mutbl) => { ty::RawPtr(ty::TypeAndMut { ty, mutbl }) | ty::Ref(_, ty, mutbl) => {
mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, tys) mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, tys)

View file

@ -21,11 +21,11 @@ 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).subst_identity().output()) && let ty = cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).instantiate_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(_, args) = ty.kind()
{ {
let err_ty = substs.type_at(1); let err_ty = args.type_at(1);
Some((hir_ty, err_ty)) Some((hir_ty, err_ty))
} else { } else {
None None

View file

@ -63,10 +63,10 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
return; return;
} }
let ret_ty = return_ty(cx, cx.tcx.hir().local_def_id_to_hir_id(fn_def_id).expect_owner()); 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, args, .. }) = *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;
for (p, _span) in preds.subst_iter_copied(cx.tcx, substs) { for (p, _span) in preds.arg_iter_copied(cx.tcx, args) {
if let Some(trait_pred) = p.as_trait_clause() { if let Some(trait_pred) = p.as_trait_clause() {
if Some(trait_pred.skip_binder().trait_ref.def_id) == cx.tcx.lang_items().future_trait() { if Some(trait_pred.skip_binder().trait_ref.def_id) == cx.tcx.lang_items().future_trait() {
is_future = true; is_future = true;

View file

@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
if let Some(const_id) = cx.typeck_results().type_dependent_def_id(cond_num_val.hir_id); if let Some(const_id) = cx.typeck_results().type_dependent_def_id(cond_num_val.hir_id);
if let Some(impl_id) = cx.tcx.impl_of_method(const_id); if let Some(impl_id) = cx.tcx.impl_of_method(const_id);
if let None = cx.tcx.impl_trait_ref(impl_id); // An inherent impl if let None = cx.tcx.impl_trait_ref(impl_id); // An inherent impl
if cx.tcx.type_of(impl_id).subst_identity().is_integral(); if cx.tcx.type_of(impl_id).instantiate_identity().is_integral();
then { then {
print_lint_and_sugg(cx, var_name, expr) print_lint_and_sugg(cx, var_name, expr)
} }
@ -115,7 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
if let Some(func_id) = cx.typeck_results().type_dependent_def_id(func.hir_id); if let Some(func_id) = cx.typeck_results().type_dependent_def_id(func.hir_id);
if let Some(impl_id) = cx.tcx.impl_of_method(func_id); if let Some(impl_id) = cx.tcx.impl_of_method(func_id);
if let None = cx.tcx.impl_trait_ref(impl_id); // An inherent impl if let None = cx.tcx.impl_trait_ref(impl_id); // An inherent impl
if cx.tcx.type_of(impl_id).subst_identity().is_integral(); if cx.tcx.type_of(impl_id).instantiate_identity().is_integral();
then { then {
print_lint_and_sugg(cx, var_name, expr) print_lint_and_sugg(cx, var_name, expr)
} }

View file

@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {
) )
}) { }) {
for impl_id in impl_ids.iter().map(|id| id.expect_local()) { for impl_id in impl_ids.iter().map(|id| id.expect_local()) {
let impl_ty = cx.tcx.type_of(impl_id).subst_identity(); let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity();
match type_map.entry(impl_ty) { match type_map.entry(impl_ty) {
Entry::Vacant(e) => { Entry::Vacant(e) => {
// Store the id for the first impl block of this type. The span is retrieved lazily. // Store the id for the first impl block of this type. The span is retrieved lazily.

View file

@ -68,7 +68,7 @@ fn check_sig(cx: &LateContext<'_>, name: &str, sig: &FnSig<'_>, fn_id: LocalDefI
if sig.decl.implicit_self.has_implicit_self() { if sig.decl.implicit_self.has_implicit_self() {
let ret_ty = cx let ret_ty = cx
.tcx .tcx
.erase_late_bound_regions(cx.tcx.fn_sig(fn_id).subst_identity().output()); .erase_late_bound_regions(cx.tcx.fn_sig(fn_id).instantiate_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

@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
return; return;
} }
if let ItemKind::Enum(ref def, _) = item.kind { if let ItemKind::Enum(ref def, _) = item.kind {
let ty = cx.tcx.type_of(item.owner_id).subst_identity(); let ty = cx.tcx.type_of(item.owner_id).instantiate_identity();
let Adt(adt, subst) = ty.kind() else { let Adt(adt, subst) = ty.kind() else {
panic!("already checked whether this is an enum") panic!("already checked whether this is an enum")
}; };
@ -169,8 +169,8 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
} }
fn maybe_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { fn maybe_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
if let Adt(_def, substs) = ty.kind() if let Adt(_def, args) = ty.kind()
&& substs.types().next().is_some() && args.types().next().is_some()
&& let Some(copy_trait) = cx.tcx.lang_items().copy_trait() && let Some(copy_trait) = cx.tcx.lang_items().copy_trait()
{ {
return cx.tcx.non_blanket_impls_for_ty(copy_trait, ty).next().is_some(); return cx.tcx.non_blanket_impls_for_ty(copy_trait, ty).next().is_some();

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).subst_identity().skip_binder()); if let Some(output) = parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).instantiate_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"),
@ -425,7 +425,7 @@ fn check_for_is_empty(
if !(is_empty.fn_has_self_parameter if !(is_empty.fn_has_self_parameter
&& check_is_empty_sig( && check_is_empty_sig(
cx, cx,
cx.tcx.fn_sig(is_empty.def_id).subst_identity().skip_binder(), cx.tcx.fn_sig(is_empty.def_id).instantiate_identity().skip_binder(),
self_kind, self_kind,
output, output,
)) => )) =>

View file

@ -5,7 +5,7 @@ use clippy_utils::{is_must_use_func_call, paths};
use rustc_hir::{Local, PatKind}; use rustc_hir::{Local, PatKind};
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_middle::ty::subst::GenericArgKind; use rustc_middle::ty::GenericArgKind;
use rustc_middle::ty::IsSuggestable; use rustc_middle::ty::IsSuggestable;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{BytePos, Span}; use rustc_span::{BytePos, Span};

View file

@ -125,7 +125,7 @@ fn is_ref_iterable<'tcx>(
} }
let res_ty = cx.tcx.erase_regions(EarlyBinder::bind(req_res_ty) let res_ty = cx.tcx.erase_regions(EarlyBinder::bind(req_res_ty)
.subst(cx.tcx, typeck.node_substs(call_expr.hir_id))); .instantiate(cx.tcx, typeck.node_args(call_expr.hir_id)));
let mutbl = if let ty::Ref(_, _, mutbl) = *req_self_ty.kind() { let mutbl = if let ty::Ref(_, _, mutbl) = *req_self_ty.kind() {
Some(mutbl) Some(mutbl)
} else { } else {

View file

@ -35,7 +35,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, body: &'
if let ExprKind::Block(Block { stmts: [], expr: None, ..}, _) = body.kind; if let ExprKind::Block(Block { stmts: [], expr: None, ..}, _) = body.kind;
if let ExprKind::MethodCall(method, callee, ..) = unpack_cond(cond).kind; if let ExprKind::MethodCall(method, callee, ..) = unpack_cond(cond).kind;
if [sym::load, sym::compare_exchange, sym::compare_exchange_weak].contains(&method.ident.name); if [sym::load, sym::compare_exchange, sym::compare_exchange_weak].contains(&method.ident.name);
if let ty::Adt(def, _substs) = cx.typeck_results().expr_ty(callee).kind(); if let ty::Adt(def, _args) = cx.typeck_results().expr_ty(callee).kind();
if cx.tcx.is_diagnostic_item(sym::AtomicBool, def.did()); if cx.tcx.is_diagnostic_item(sym::AtomicBool, def.did());
then { then {
span_lint_and_sugg( span_lint_and_sugg(

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).subst_identity().inputs().skip_binder(), self.cx.tcx.fn_sig(def_id).instantiate_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

@ -110,7 +110,7 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<
if let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id(); if let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id();
if cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id); if cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id);
then { then {
cx.typeck_results().node_substs(count_func.hir_id).types().next().map(|resolved_ty| (*real_ty, resolved_ty)) cx.typeck_results().node_args(count_func.hir_id).types().next().map(|resolved_ty| (*real_ty, resolved_ty))
} else { } else {
None None
} }

View file

@ -92,7 +92,7 @@ fn simplify_half<'tcx>(
&& let ExprKind::Path(ref func_qpath) = func.kind && let ExprKind::Path(ref func_qpath) = func.kind
&& let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id() && let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id()
&& cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id) && cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id)
&& let Some(ty2) = cx.typeck_results().node_substs(func.hir_id).types().next() && let Some(ty2) = cx.typeck_results().node_args(func.hir_id).types().next()
// T1 == T2? // T1 == T2?
&& *ty1 == ty2 && *ty1 == ty2
{ {

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).subst_identity().no_bound_vars() { if let Some(fn_type) = cx.tcx.fn_sig(id).instantiate_identity().no_bound_vars() {
return is_unit_type(fn_type.output()); return is_unit_type(fn_type.output());
} }
} }

View file

@ -27,10 +27,10 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr:
let input_ty = cx.typeck_results().expr_ty(ex); let input_ty = cx.typeck_results().expr_ty(ex);
let cast = if_chain! { let cast = if_chain! {
if let ty::Adt(_, substs) = input_ty.kind(); if let ty::Adt(_, args) = input_ty.kind();
let input_ty = substs.type_at(0); let input_ty = args.type_at(0);
if let ty::Adt(_, substs) = output_ty.kind(); if let ty::Adt(_, args) = output_ty.kind();
let output_ty = substs.type_at(0); let output_ty = args.type_at(0);
if let ty::Ref(_, output_ty, _) = *output_ty.kind(); if let ty::Ref(_, output_ty, _) = *output_ty.kind();
if input_ty != output_ty; if input_ty != output_ty;
then { then {

View file

@ -12,7 +12,7 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::LangItem::{self, OptionNone, OptionSome, PollPending, PollReady, ResultErr, ResultOk}; use rustc_hir::LangItem::{self, OptionNone, OptionSome, PollPending, PollReady, ResultErr, ResultOk};
use rustc_hir::{Arm, Expr, ExprKind, Node, Pat, PatKind, QPath, UnOp}; use rustc_hir::{Arm, Expr, ExprKind, Node, Pat, PatKind, QPath, UnOp};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{self, subst::GenericArgKind, Ty}; use rustc_middle::ty::{self, GenericArgKind, Ty};
use rustc_span::{sym, Symbol}; use rustc_span::{sym, Symbol};
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {

View file

@ -10,7 +10,7 @@ pub(crate) fn check(cx: &LateContext<'_>, pat: &Pat<'_>) {
if !pat.span.from_expansion(); if !pat.span.from_expansion();
if let PatKind::Struct(QPath::Resolved(_, path), fields, true) = pat.kind; if let PatKind::Struct(QPath::Resolved(_, path), fields, true) = pat.kind;
if let Some(def_id) = path.res.opt_def_id(); if let Some(def_id) = path.res.opt_def_id();
let ty = cx.tcx.type_of(def_id).subst_identity(); let ty = cx.tcx.type_of(def_id).instantiate_identity();
if let ty::Adt(def, _) = ty.kind(); if let ty::Adt(def, _) = ty.kind();
if def.is_struct() || def.is_union(); if def.is_struct() || def.is_union();
if fields.len() == def.non_enum_variant().fields.len(); if fields.len() == def.non_enum_variant().fields.len();

View file

@ -6,7 +6,7 @@ use rustc_errors::{Applicability, Diagnostic};
use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{Arm, Expr, ExprKind, MatchSource}; use rustc_hir::{Arm, Expr, ExprKind, MatchSource};
use rustc_lint::{LateContext, LintContext}; use rustc_lint::{LateContext, LintContext};
use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::GenericArgKind;
use rustc_middle::ty::{Ty, TypeAndMut}; use rustc_middle::ty::{Ty, TypeAndMut};
use rustc_span::Span; use rustc_span::Span;

View file

@ -17,7 +17,7 @@ pub(super) fn check<'tcx>(
if_chain! { if_chain! {
if let Some(bytes_id) = cx.typeck_results().type_dependent_def_id(count_recv.hir_id); if let Some(bytes_id) = cx.typeck_results().type_dependent_def_id(count_recv.hir_id);
if let Some(impl_id) = cx.tcx.impl_of_method(bytes_id); if let Some(impl_id) = cx.tcx.impl_of_method(bytes_id);
if cx.tcx.type_of(impl_id).subst_identity().is_str(); if cx.tcx.type_of(impl_id).instantiate_identity().is_str();
let ty = cx.typeck_results().expr_ty(bytes_recv).peel_refs(); let ty = cx.typeck_results().expr_ty(bytes_recv).peel_refs();
if ty.is_str() || is_type_lang_item(cx, ty, hir::LangItem::String); if ty.is_str() || is_type_lang_item(cx, ty, hir::LangItem::String);
then { then {

View file

@ -30,7 +30,7 @@ pub(super) fn check<'tcx>(
if_chain! { if_chain! {
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
if let Some(impl_id) = cx.tcx.impl_of_method(method_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
if cx.tcx.type_of(impl_id).subst_identity().is_str(); if cx.tcx.type_of(impl_id).instantiate_identity().is_str();
if let ExprKind::Lit(Spanned { node: LitKind::Str(ext_literal, ..), ..}) = arg.kind; if let ExprKind::Lit(Spanned { node: LitKind::Str(ext_literal, ..), ..}) = arg.kind;
if (2..=6).contains(&ext_literal.as_str().len()); if (2..=6).contains(&ext_literal.as_str().len());
let ext_str = ext_literal.as_str(); let ext_str = ext_literal.as_str();

View file

@ -47,7 +47,7 @@ pub(super) fn check(
/// Given a `Result<T, E>` type, return its data (`T`). /// Given a `Result<T, E>` type, return its data (`T`).
fn get_data_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option<Ty<'a>> { fn get_data_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option<Ty<'a>> {
match ty.kind() { match ty.kind() {
ty::Adt(_, substs) if is_type_diagnostic_item(cx, ty, sym::Result) => substs.types().next(), ty::Adt(_, args) if is_type_diagnostic_item(cx, ty, sym::Result) => args.types().next(),
_ => None, _ => None,
} }
} }

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).subst_identity().output().skip_binder().kind(), cx.tcx.fn_sig(def_id).instantiate_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).subst_identity().output().skip_binder().kind(), cx.tcx.fn_sig(method_id).instantiate_identity().output().skip_binder().kind(),
ty::Ref(re, ..) if re.is_static() ty::Ref(re, ..) if re.is_static()
) )
}) })

View file

@ -15,7 +15,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, arg
} }
let arg_ty = cx.typeck_results().expr_ty_adjusted(arg); let arg_ty = cx.typeck_results().expr_ty_adjusted(arg);
let sig = match arg_ty.kind() { let sig = match arg_ty.kind() {
ty::Closure(_, substs) => substs.as_closure().sig(), ty::Closure(_, args) => args.as_closure().sig(),
_ if arg_ty.is_fn() => arg_ty.fn_sig(cx.tcx), _ if arg_ty.is_fn() => arg_ty.fn_sig(cx.tcx),
_ => return, _ => return,
}; };

View file

@ -19,7 +19,7 @@ pub(super) fn check<'tcx>(
if_chain! { if_chain! {
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
if let Some(impl_id) = cx.tcx.impl_of_method(method_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
if cx.tcx.type_of(impl_id).subst_identity().is_slice(); if cx.tcx.type_of(impl_id).instantiate_identity().is_slice();
if let Some(_) = is_slice_of_primitives(cx, recv); if let Some(_) = is_slice_of_primitives(cx, recv);
if let hir::ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = arg.kind; if let hir::ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = arg.kind;
then { then {

View file

@ -54,7 +54,7 @@ pub fn is_clone_like(cx: &LateContext<'_>, method_name: &str, method_def_id: hir
.tcx .tcx
.impl_of_method(method_def_id) .impl_of_method(method_def_id)
.filter(|&impl_did| { .filter(|&impl_did| {
cx.tcx.type_of(impl_did).subst_identity().is_slice() && cx.tcx.impl_trait_ref(impl_did).is_none() cx.tcx.type_of(impl_did).instantiate_identity().is_slice() && cx.tcx.impl_trait_ref(impl_did).is_none()
}) })
.is_some(), .is_some(),
_ => false, _ => false,

View file

@ -23,9 +23,9 @@ pub fn check(
if args.is_empty() && method_name == sym::to_string; if args.is_empty() && method_name == sym::to_string;
if let Some(to_string_meth_did) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(to_string_meth_did) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
if match_def_path(cx, to_string_meth_did, &paths::TO_STRING_METHOD); if match_def_path(cx, to_string_meth_did, &paths::TO_STRING_METHOD);
if let Some(substs) = cx.typeck_results().node_substs_opt(expr.hir_id); if let Some(args) = cx.typeck_results().node_args_opt(expr.hir_id);
let arg_ty = cx.typeck_results().expr_ty_adjusted(receiver); let arg_ty = cx.typeck_results().expr_ty_adjusted(receiver);
let self_ty = substs.type_at(0); let self_ty = args.type_at(0);
let (deref_self_ty, deref_count) = walk_ptrs_ty_depth(self_ty); let (deref_self_ty, deref_count) = walk_ptrs_ty_depth(self_ty);
if deref_count >= 1; if deref_count >= 1;
if specializes_tostring(cx, deref_self_ty); if specializes_tostring(cx, deref_self_ty);
@ -64,8 +64,8 @@ fn specializes_tostring(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
return true; return true;
} }
if let ty::Adt(adt, substs) = ty.kind() { if let ty::Adt(adt, args) = ty.kind() {
cx.tcx.is_diagnostic_item(sym::Cow, adt.did()) && substs.type_at(1).is_str() cx.tcx.is_diagnostic_item(sym::Cow, adt.did()) && args.type_at(1).is_str()
} else { } else {
false false
} }

View file

@ -21,7 +21,7 @@ pub(super) fn check<'tcx>(
if_chain! { if_chain! {
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
if let Some(impl_id) = cx.tcx.impl_of_method(method_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::Option); if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::Option);
if let ExprKind::Call(err_path, [err_arg]) = or_expr.kind; if let ExprKind::Call(err_path, [err_arg]) = or_expr.kind;
if is_res_lang_ctor(cx, path_res(cx, err_path), ResultErr); if is_res_lang_ctor(cx, path_res(cx, err_path), ResultErr);
if is_ok_wrapping(cx, map_expr); if is_ok_wrapping(cx, map_expr);

View file

@ -19,7 +19,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_
if_chain! { if_chain! {
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id); if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id);
if cx.tcx.impl_of_method(method_id) if cx.tcx.impl_of_method(method_id)
.map_or(false, |id| is_type_diagnostic_item(cx, cx.tcx.type_of(id).subst_identity(), sym::Option)) .map_or(false, |id| is_type_diagnostic_item(cx, cx.tcx.type_of(id).instantiate_identity(), sym::Option))
|| is_diag_trait_item(cx, method_id, sym::Iterator); || is_diag_trait_item(cx, method_id, sym::Iterator);
if let hir::ExprKind::Closure(&hir::Closure{ body, .. }) = arg.kind; if let hir::ExprKind::Closure(&hir::Closure{ body, .. }) = arg.kind;
then { then {

View file

@ -15,8 +15,8 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, iter: &hir::Expr
let collect_ret_ty = cx.typeck_results().expr_ty(expr); let collect_ret_ty = cx.typeck_results().expr_ty(expr);
if_chain! { if_chain! {
if is_type_diagnostic_item(cx, collect_ret_ty, sym::Result); if is_type_diagnostic_item(cx, collect_ret_ty, sym::Result);
if let ty::Adt(_, substs) = collect_ret_ty.kind(); if let ty::Adt(_, args) = collect_ret_ty.kind();
if let Some(result_t) = substs.types().next(); if let Some(result_t) = args.types().next();
if result_t.is_unit(); if result_t.is_unit();
// get parts for snippet // get parts for snippet
then { then {

View file

@ -9,7 +9,7 @@ use super::MAP_ERR_IGNORE;
pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, arg: &Expr<'_>) { pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, arg: &Expr<'_>) {
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
&& let Some(impl_id) = cx.tcx.impl_of_method(method_id) && let Some(impl_id) = cx.tcx.impl_of_method(method_id)
&& is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::Result) && is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::Result)
&& let ExprKind::Closure(&Closure { && let ExprKind::Closure(&Closure {
capture_clause: CaptureBy::Ref, capture_clause: CaptureBy::Ref,
body, body,

View file

@ -59,7 +59,7 @@ fn is_map_to_option(cx: &LateContext<'_>, map_arg: &Expr<'_>) -> bool {
match map_closure_ty.kind() { match map_closure_ty.kind() {
ty::Closure(_, _) | ty::FnDef(_, _) | ty::FnPtr(_) => { ty::Closure(_, _) | ty::FnDef(_, _) | ty::FnPtr(_) => {
let map_closure_sig = match map_closure_ty.kind() { let map_closure_sig = match map_closure_ty.kind() {
ty::Closure(_, substs) => substs.as_closure().sig(), ty::Closure(_, args) => args.as_closure().sig(),
_ => map_closure_ty.fn_sig(cx.tcx), _ => map_closure_ty.fn_sig(cx.tcx),
}; };
let map_closure_return_ty = cx.tcx.erase_late_bound_regions(map_closure_sig.output()); let map_closure_return_ty = cx.tcx.erase_late_bound_regions(map_closure_sig.output());

View file

@ -3508,11 +3508,11 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
let name = impl_item.ident.name.as_str(); let name = impl_item.ident.name.as_str();
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).subst_identity(); let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity();
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).subst_identity(); let method_sig = cx.tcx.fn_sig(impl_item.owner_id).instantiate_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
@ -4113,8 +4113,8 @@ impl SelfKind {
} else if ty.is_box() { } else if ty.is_box() {
ty.boxed_ty() == parent_ty ty.boxed_ty() == parent_ty
} else if is_type_diagnostic_item(cx, ty, sym::Rc) || is_type_diagnostic_item(cx, ty, sym::Arc) { } else if is_type_diagnostic_item(cx, ty, sym::Rc) || is_type_diagnostic_item(cx, ty, sym::Arc) {
if let ty::Adt(_, substs) = ty.kind() { if let ty::Adt(_, args) = ty.kind() {
substs.types().next().map_or(false, |t| t == parent_ty) args.types().next().map_or(false, |t| t == parent_ty)
} else { } else {
false false
} }

View file

@ -15,7 +15,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'tcx>, recv: &'
if let ty::Ref(_, _, Mutability::Mut) = cx.typeck_results().expr_ty(recv).kind(); if let ty::Ref(_, _, Mutability::Mut) = cx.typeck_results().expr_ty(recv).kind();
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(ex.hir_id); if let Some(method_id) = cx.typeck_results().type_dependent_def_id(ex.hir_id);
if let Some(impl_id) = cx.tcx.impl_of_method(method_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::Mutex); if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::Mutex);
then { then {
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,

View file

@ -163,7 +163,7 @@ fn check_collect_into_intoiterator<'tcx>(
// that contains `collect_expr` // that contains `collect_expr`
let inputs = cx let inputs = cx
.tcx .tcx
.liberate_late_bound_regions(id, cx.tcx.fn_sig(id).subst_identity()) .liberate_late_bound_regions(id, cx.tcx.fn_sig(id).instantiate_identity())
.inputs(); .inputs();
// map IntoIterator generic bounds to their signature // map IntoIterator generic bounds to their signature
@ -201,7 +201,7 @@ fn check_collect_into_intoiterator<'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).subst_identity().skip_binder(); let sig = cx.tcx.fn_sig(id).instantiate_identity().skip_binder();
sig.inputs().len() == 1 && sig.output().is_bool() sig.inputs().len() == 1 && sig.output().is_bool()
}) })
} }
@ -215,7 +215,7 @@ fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty:
&& let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, item, [collect_ty]) && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, item, [collect_ty])
&& let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions( && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions(
cx.param_env, cx.param_env,
Ty::new_projection(cx.tcx,into_iter_item_proj.def_id, into_iter_item_proj.substs) Ty::new_projection(cx.tcx,into_iter_item_proj.def_id, into_iter_item_proj.args)
) )
{ {
iter_item_ty == into_iter_item_ty iter_item_ty == into_iter_item_ty
@ -229,7 +229,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).subst_identity() && let sig = cx.tcx.fn_sig(id).instantiate_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()
@ -237,11 +237,11 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -
&& let Some(iter_item) = cx.tcx && let Some(iter_item) = cx.tcx
.associated_items(iter_trait) .associated_items(iter_trait)
.find_by_name_and_kind(cx.tcx, Ident::with_dummy_span(Symbol::intern("Item")), AssocKind::Type, iter_trait) .find_by_name_and_kind(cx.tcx, Ident::with_dummy_span(Symbol::intern("Item")), AssocKind::Type, iter_trait)
&& let substs = cx.tcx.mk_substs(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) && let args = cx.tcx.mk_args(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))])
&& let proj_ty = Ty::new_projection(cx.tcx,iter_item.def_id, substs) && let proj_ty = Ty::new_projection(cx.tcx,iter_item.def_id, args)
&& let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty) && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty)
{ {
item_ty == EarlyBinder::bind(search_ty).subst(cx.tcx, cx.typeck_results().node_substs(call_id)) item_ty == EarlyBinder::bind(search_ty).instantiate(cx.tcx, cx.typeck_results().node_args(call_id))
} else { } else {
false false
} }

View file

@ -33,7 +33,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
/// Given a `Result<T, E>` type, return its error type (`E`). /// Given a `Result<T, E>` type, return its error type (`E`).
fn get_error_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option<Ty<'a>> { fn get_error_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option<Ty<'a>> {
match ty.kind() { match ty.kind() {
ty::Adt(_, substs) if is_type_diagnostic_item(cx, ty, sym::Result) => substs.types().nth(1), ty::Adt(_, args) if is_type_diagnostic_item(cx, ty, sym::Result) => args.types().nth(1),
_ => None, _ => None,
} }
} }

View file

@ -11,7 +11,7 @@ use super::NONSENSICAL_OPEN_OPTIONS;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) { pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) {
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
&& let Some(impl_id) = cx.tcx.impl_of_method(method_id) && let Some(impl_id) = cx.tcx.impl_of_method(method_id)
&& match_type(cx, cx.tcx.type_of(impl_id).subst_identity(), &paths::OPEN_OPTIONS) && match_type(cx, cx.tcx.type_of(impl_id).instantiate_identity(), &paths::OPEN_OPTIONS)
{ {
let mut options = Vec::new(); let mut options = Vec::new();
get_open_options(cx, recv, &mut options); get_open_options(cx, recv, &mut options);

View file

@ -14,7 +14,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t
if_chain! { if_chain! {
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
if let Some(impl_id) = cx.tcx.impl_of_method(method_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::PathBuf); if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::PathBuf);
if let ExprKind::Lit(lit) = arg.kind; if let ExprKind::Lit(lit) = arg.kind;
if let LitKind::Str(ref path_lit, _) = lit.node; if let LitKind::Str(ref path_lit, _) = lit.node;
if let pushed_path = Path::new(path_lit.as_str()); if let pushed_path = Path::new(path_lit.as_str());

View file

@ -10,7 +10,7 @@ use super::STABLE_SORT_PRIMITIVE;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) { pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) {
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
&& let Some(impl_id) = cx.tcx.impl_of_method(method_id) && let Some(impl_id) = cx.tcx.impl_of_method(method_id)
&& cx.tcx.type_of(impl_id).subst_identity().is_slice() && cx.tcx.type_of(impl_id).instantiate_identity().is_slice()
&& let Some(slice_type) = is_slice_of_primitives(cx, recv) && let Some(slice_type) = is_slice_of_primitives(cx, recv)
{ {
span_lint_and_then( span_lint_and_then(

View file

@ -13,7 +13,7 @@ pub(super) fn check(cx: &LateContext<'_>, method_name: &str, expr: &Expr<'_>, se
if let Some(call_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(call_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
if let Some(impl_id) = cx.tcx.impl_of_method(call_id); if let Some(impl_id) = cx.tcx.impl_of_method(call_id);
if cx.tcx.impl_trait_ref(impl_id).is_none(); if cx.tcx.impl_trait_ref(impl_id).is_none();
let self_ty = cx.tcx.type_of(impl_id).subst_identity(); let self_ty = cx.tcx.type_of(impl_id).instantiate_identity();
if self_ty.is_slice() || self_ty.is_str(); if self_ty.is_slice() || self_ty.is_str();
then { then {
// Ignore empty slice and string literals when used with a literal count. // Ignore empty slice and string literals when used with a literal count.

View file

@ -6,7 +6,7 @@ use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Closure, Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath}; use rustc_hir::{Closure, Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{self, subst::GenericArgKind}; use rustc_middle::ty::{self, GenericArgKind};
use rustc_span::sym; use rustc_span::sym;
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
use std::iter; use std::iter;
@ -118,7 +118,7 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Exp
if_chain! { if_chain! {
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
if let Some(impl_id) = cx.tcx.impl_of_method(method_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
if cx.tcx.type_of(impl_id).subst_identity().is_slice(); if cx.tcx.type_of(impl_id).instantiate_identity().is_slice();
if let ExprKind::Closure(&Closure { body, .. }) = arg.kind; if let ExprKind::Closure(&Closure { body, .. }) = arg.kind;
if let closure_body = cx.tcx.hir().body(body); if let closure_body = cx.tcx.hir().body(body);
if let &[ if let &[

View file

@ -13,7 +13,7 @@ use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::mir::Mutability; use rustc_middle::mir::Mutability;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgsRef};
use rustc_middle::ty::{self, ClauseKind, EarlyBinder, ParamTy, ProjectionPredicate, TraitPredicate, Ty}; use rustc_middle::ty::{self, ClauseKind, EarlyBinder, ParamTy, ProjectionPredicate, TraitPredicate, Ty};
use rustc_span::{sym, Symbol}; use rustc_span::{sym, Symbol};
use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause}; use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause};
@ -250,8 +250,8 @@ fn check_other_call_arg<'tcx>(
) -> bool { ) -> bool {
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_generic_args_and_args(cx, maybe_call);
let fn_sig = cx.tcx.fn_sig(callee_def_id).subst_identity().skip_binder(); let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_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);
@ -315,26 +315,26 @@ fn skip_addr_of_ancestors<'tcx>(
} }
/// Checks whether an expression is a function or method call and, if so, returns its `DefId`, /// Checks whether an expression is a function or method call and, if so, returns its `DefId`,
/// `Substs`, and arguments. /// `GenericArgs`, and arguments.
fn get_callee_substs_and_args<'tcx>( fn get_callee_generic_args_and_args<'tcx>(
cx: &LateContext<'tcx>, cx: &LateContext<'tcx>,
expr: &'tcx Expr<'tcx>, expr: &'tcx Expr<'tcx>,
) -> Option<(DefId, SubstsRef<'tcx>, Option<&'tcx Expr<'tcx>>, &'tcx [Expr<'tcx>])> { ) -> Option<(DefId, GenericArgsRef<'tcx>, Option<&'tcx Expr<'tcx>>, &'tcx [Expr<'tcx>])> {
if_chain! { if_chain! {
if let ExprKind::Call(callee, args) = expr.kind; if let ExprKind::Call(callee, args) = expr.kind;
let callee_ty = cx.typeck_results().expr_ty(callee); let callee_ty = cx.typeck_results().expr_ty(callee);
if let ty::FnDef(callee_def_id, _) = callee_ty.kind(); if let ty::FnDef(callee_def_id, _) = callee_ty.kind();
then { then {
let substs = cx.typeck_results().node_substs(callee.hir_id); let generic_args = cx.typeck_results().node_args(callee.hir_id);
return Some((*callee_def_id, substs, None, args)); return Some((*callee_def_id, generic_args, None, args));
} }
} }
if_chain! { if_chain! {
if let ExprKind::MethodCall(_, recv, args, _) = expr.kind; if let ExprKind::MethodCall(_, recv, args, _) = expr.kind;
if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
then { then {
let substs = cx.typeck_results().node_substs(expr.hir_id); let generic_args = cx.typeck_results().node_args(expr.hir_id);
return Some((method_def_id, substs, Some(recv), args)); return Some((method_def_id, generic_args, Some(recv), args));
} }
} }
None None
@ -388,17 +388,17 @@ 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_generic_args, recv, call_args)) = get_callee_generic_args_and_args(cx, parent_expr)
{ {
// FIXME: the `subst_identity()` below seems incorrect, since we eventually // FIXME: the `instantiate_identity()` below seems incorrect, since we eventually
// call `tcx.try_subst_and_normalize_erasing_regions` further down // call `tcx.try_subst_and_normalize_erasing_regions` further down
// (i.e., we are explicitly not in the identity context). // (i.e., we are explicitly not in the identity context).
let fn_sig = cx.tcx.fn_sig(callee_def_id).subst_identity().skip_binder(); let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_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()
// https://github.com/rust-lang/rust-clippy/issues/9504 and https://github.com/rust-lang/rust-clippy/issues/10021 // https://github.com/rust-lang/rust-clippy/issues/9504 and https://github.com/rust-lang/rust-clippy/issues/10021
&& (*param_index as usize) < call_substs.len() && (*param_index as usize) < call_generic_args.len()
{ {
if fn_sig if fn_sig
.inputs() .inputs()
@ -422,8 +422,8 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
} }
}); });
let new_subst = cx.tcx.mk_substs_from_iter( let new_subst = cx.tcx.mk_args_from_iter(
call_substs.iter() call_generic_args.iter()
.enumerate() .enumerate()
.map(|(i, t)| .map(|(i, t)|
if i == (*param_index as usize) { if i == (*param_index as usize) {
@ -433,7 +433,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
})); }));
if trait_predicates.any(|predicate| { if trait_predicates.any(|predicate| {
let predicate = EarlyBinder::bind(predicate).subst(cx.tcx, new_subst); let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, new_subst);
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate); let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
!cx.tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation) !cx.tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation)
}) { }) {
@ -500,8 +500,8 @@ fn is_to_string_on_string_like<'a>(
return false; return false;
} }
if let Some(substs) = cx.typeck_results().node_substs_opt(call_expr.hir_id) if let Some(args) = cx.typeck_results().node_args_opt(call_expr.hir_id)
&& let [generic_arg] = substs.as_slice() && let [generic_arg] = args.as_slice()
&& let GenericArgKind::Type(ty) = generic_arg.unpack() && let GenericArgKind::Type(ty) = generic_arg.unpack()
&& let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref) && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)
&& let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef) && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef)

View file

@ -143,7 +143,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'cx, 'tcx> {
if_chain! { if_chain! {
if args.iter().all(|arg| !self.is_binding(arg)); if args.iter().all(|arg| !self.is_binding(arg));
if let Some(method_def_id) = self.cx.typeck_results().type_dependent_def_id(parent.hir_id); if let Some(method_def_id) = self.cx.typeck_results().type_dependent_def_id(parent.hir_id);
let method_ty = self.cx.tcx.type_of(method_def_id).subst_identity(); let method_ty = self.cx.tcx.type_of(method_def_id).instantiate_identity();
let self_ty = method_ty.fn_sig(self.cx.tcx).input(0).skip_binder(); let self_ty = method_ty.fn_sig(self.cx.tcx).input(0).skip_binder();
if matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Not)); if matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Not));
then { then {

View file

@ -20,7 +20,7 @@ pub(super) fn check<'tcx>(
if_chain! { if_chain! {
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
if let Some(impl_id) = cx.tcx.impl_of_method(method_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::Vec); if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::Vec);
if let ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = count_arg.kind; if let ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = count_arg.kind;
if let ExprKind::Lit(Spanned { node: LitKind::Int(..), .. }) = default_arg.kind; if let ExprKind::Lit(Spanned { node: LitKind::Int(..), .. }) = default_arg.kind;
then { then {

View file

@ -139,7 +139,7 @@ impl MutableKeyType {
} }
fn check_sig(&self, cx: &LateContext<'_>, fn_def_id: LocalDefId, decl: &hir::FnDecl<'_>) { fn check_sig(&self, cx: &LateContext<'_>, fn_def_id: LocalDefId, decl: &hir::FnDecl<'_>) {
let fn_sig = cx.tcx.fn_sig(fn_def_id).subst_identity(); let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity();
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);
} }
@ -150,7 +150,7 @@ impl MutableKeyType {
// generics (because the compiler cannot ensure immutability for unknown types). // generics (because the compiler cannot ensure immutability for unknown types).
fn check_ty_<'tcx>(&self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) { fn check_ty_<'tcx>(&self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) {
let ty = ty.peel_refs(); let ty = ty.peel_refs();
if let Adt(def, substs) = ty.kind() { if let Adt(def, args) = ty.kind() {
let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet] let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet]
.iter() .iter()
.any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did())); .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did()));
@ -158,7 +158,7 @@ impl MutableKeyType {
return; return;
} }
let subst_ty = substs.type_at(0); let subst_ty = args.type_at(0);
// Determines if a type contains interior mutability which would affect its implementation of // Determines if a type contains interior mutability which would affect its implementation of
// [`Hash`] or [`Ord`]. // [`Hash`] or [`Ord`].
if is_interior_mut_ty(cx, subst_ty) if is_interior_mut_ty(cx, subst_ty)

View file

@ -51,8 +51,8 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed {
}, },
ExprKind::MethodCall(path, receiver, arguments, _) => { ExprKind::MethodCall(path, receiver, arguments, _) => {
let def_id = cx.typeck_results().type_dependent_def_id(e.hir_id).unwrap(); let def_id = cx.typeck_results().type_dependent_def_id(e.hir_id).unwrap();
let substs = cx.typeck_results().node_substs(e.hir_id); let args = cx.typeck_results().node_args(e.hir_id);
let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs); let method_type = cx.tcx.type_of(def_id).instantiate(cx.tcx, args);
check_arguments( check_arguments(
cx, cx,
std::iter::once(receiver).chain(arguments.iter()).collect(), std::iter::once(receiver).chain(arguments.iter()).collect(),

View file

@ -140,7 +140,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
ctx ctx
}; };
let fn_sig = cx.tcx.fn_sig(fn_def_id).subst_identity(); let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity();
let fn_sig = cx.tcx.liberate_late_bound_regions(fn_def_id.to_def_id(), fn_sig); let fn_sig = cx.tcx.liberate_late_bound_regions(fn_def_id.to_def_id(), 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() {
@ -170,7 +170,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
!preds.is_empty() && { !preds.is_empty() && {
let ty_empty_region = Ty::new_imm_ref(cx.tcx,cx.tcx.lifetimes.re_erased, ty); let ty_empty_region = Ty::new_imm_ref(cx.tcx,cx.tcx.lifetimes.re_erased, ty);
preds.iter().all(|t| { preds.iter().all(|t| {
let ty_params = t.trait_ref.substs.iter().skip(1).collect::<Vec<_>>(); let ty_params = t.trait_ref.args.iter().skip(1).collect::<Vec<_>>();
implements_trait(cx, ty_empty_region, t.def_id(), &ty_params) implements_trait(cx, ty_empty_region, t.def_id(), &ty_params)
}) })
}, },

View file

@ -98,14 +98,14 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
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.into()); let self_def_id = cx.tcx.hir().get_parent_item(id.into());
let self_ty = cx.tcx.type_of(self_def_id).subst_identity(); let self_ty = cx.tcx.type_of(self_def_id).instantiate_identity();
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);
then { then {
if self.impling_types.is_none() { if self.impling_types.is_none() {
let mut impls = HirIdSet::default(); let mut impls = HirIdSet::default();
cx.tcx.for_each_impl(default_trait_id, |d| { cx.tcx.for_each_impl(default_trait_id, |d| {
let ty = cx.tcx.type_of(d).subst_identity(); let ty = cx.tcx.type_of(d).instantiate_identity();
if let Some(ty_def) = ty.ty_adt_def() { if let Some(ty_def) = ty.ty_adt_def() {
if let Some(local_def_id) = ty_def.did().as_local() { if let Some(local_def_id) = ty_def.did().as_local() {
impls.insert(cx.tcx.hir().local_def_id_to_hir_id(local_def_id)); impls.insert(cx.tcx.hir().local_def_id_to_hir_id(local_def_id));
@ -119,7 +119,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
// generics // generics
if_chain! { if_chain! {
if let Some(ref impling_types) = self.impling_types; if let Some(ref impling_types) = self.impling_types;
let self_def = cx.tcx.type_of(self_def_id).subst_identity(); let self_def = cx.tcx.type_of(self_def_id).instantiate_identity();
if let Some(self_def) = self_def.ty_adt_def(); if let Some(self_def) = self_def.ty_adt_def();
if let Some(self_local_did) = self_def.did().as_local(); if let Some(self_local_did) = self_def.did().as_local();
let self_id = cx.tcx.hir().local_def_id_to_hir_id(self_local_did); let self_id = cx.tcx.hir().local_def_id_to_hir_id(self_local_did);

View file

@ -158,7 +158,7 @@ fn is_value_unfrozen_raw<'tcx>(
val.unwrap_branch().iter().any(|field| inner(cx, *field, ty)) val.unwrap_branch().iter().any(|field| inner(cx, *field, ty))
}, },
ty::Adt(def, _) if def.is_union() => false, ty::Adt(def, _) if def.is_union() => false,
ty::Adt(def, substs) if def.is_enum() => { ty::Adt(def, args) if def.is_enum() => {
let (&variant_index, fields) = val.unwrap_branch().split_first().unwrap(); let (&variant_index, fields) = val.unwrap_branch().split_first().unwrap();
let variant_index = let variant_index =
VariantIdx::from_u32(variant_index.unwrap_leaf().try_to_u32().ok().unwrap()); VariantIdx::from_u32(variant_index.unwrap_leaf().try_to_u32().ok().unwrap());
@ -166,10 +166,10 @@ fn is_value_unfrozen_raw<'tcx>(
def.variants()[variant_index] def.variants()[variant_index]
.fields .fields
.iter() .iter()
.map(|field| field.ty(cx.tcx, substs))).any(|(field, ty)| inner(cx, field, ty)) .map(|field| field.ty(cx.tcx, args))).any(|(field, ty)| inner(cx, field, ty))
} }
ty::Adt(def, substs) => { ty::Adt(def, args) => {
val.unwrap_branch().iter().zip(def.non_enum_variant().fields.iter().map(|field| field.ty(cx.tcx, substs))).any(|(field, ty)| inner(cx, *field, ty)) val.unwrap_branch().iter().zip(def.non_enum_variant().fields.iter().map(|field| field.ty(cx.tcx, args))).any(|(field, ty)| inner(cx, *field, ty))
} }
ty::Tuple(tys) => val.unwrap_branch().iter().zip(tys).any(|(field, ty)| inner(cx, *field, ty)), ty::Tuple(tys) => val.unwrap_branch().iter().zip(tys).any(|(field, ty)| inner(cx, *field, ty)),
_ => false, _ => false,
@ -206,8 +206,8 @@ fn is_value_unfrozen_raw<'tcx>(
fn is_value_unfrozen_poly<'tcx>(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool { fn is_value_unfrozen_poly<'tcx>(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool {
let def_id = body_id.hir_id.owner.to_def_id(); let def_id = body_id.hir_id.owner.to_def_id();
let substs = ty::InternalSubsts::identity_for_item(cx.tcx, def_id); let args = ty::GenericArgs::identity_for_item(cx.tcx, def_id);
let instance = ty::Instance::new(def_id, substs); let instance = ty::Instance::new(def_id, args);
let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None }; let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None };
let param_env = cx.tcx.param_env(def_id).with_reveal_all_normalized(cx.tcx); let param_env = cx.tcx.param_env(def_id).with_reveal_all_normalized(cx.tcx);
let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, None); let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, None);
@ -215,9 +215,9 @@ fn is_value_unfrozen_poly<'tcx>(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<
} }
fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool { fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool {
let substs = cx.typeck_results().node_substs(hir_id); let args = cx.typeck_results().node_args(hir_id);
let result = const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, substs), None); let result = const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), None);
is_value_unfrozen_raw(cx, result, ty) is_value_unfrozen_raw(cx, result, ty)
} }
@ -228,7 +228,7 @@ pub fn const_eval_resolve<'tcx>(
ct: ty::UnevaluatedConst<'tcx>, ct: ty::UnevaluatedConst<'tcx>,
span: Option<Span>, span: Option<Span>,
) -> EvalToValTreeResult<'tcx> { ) -> EvalToValTreeResult<'tcx> {
match ty::Instance::resolve(tcx, param_env, ct.def, ct.substs) { match ty::Instance::resolve(tcx, param_env, ct.def, ct.args) {
Ok(Some(instance)) => { Ok(Some(instance)) => {
let cid = GlobalId { instance, promoted: None }; let cid = GlobalId { instance, promoted: None };
tcx.const_eval_global_id_for_typeck(param_env, cid, span) tcx.const_eval_global_id_for_typeck(param_env, cid, span)
@ -347,7 +347,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
// and, in that case, the definition is *not* generic. // and, in that case, the definition is *not* generic.
cx.tcx.normalize_erasing_regions( cx.tcx.normalize_erasing_regions(
cx.tcx.param_env(of_trait_def_id), cx.tcx.param_env(of_trait_def_id),
cx.tcx.type_of(of_assoc_item).subst_identity(), cx.tcx.type_of(of_assoc_item).instantiate_identity(),
), ),
)) ))
.is_err(); .is_err();

View file

@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::{FieldDef, Item, ItemKind, Node}; use rustc_hir::{FieldDef, Item, ItemKind, Node};
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_middle::ty::{self, subst::GenericArgKind, Ty}; use rustc_middle::ty::{self, GenericArgKind, Ty};
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::sym; use rustc_span::sym;
@ -90,8 +90,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
if send_trait == trait_id; if send_trait == trait_id;
if hir_impl.polarity == ImplPolarity::Positive; if hir_impl.polarity == ImplPolarity::Positive;
if let Some(ty_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id); if let Some(ty_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id);
if let self_ty = ty_trait_ref.subst_identity().self_ty(); if let self_ty = ty_trait_ref.instantiate_identity().self_ty();
if let ty::Adt(adt_def, impl_trait_substs) = self_ty.kind(); if let ty::Adt(adt_def, impl_trait_args) = self_ty.kind();
then { then {
let mut non_send_fields = Vec::new(); let mut non_send_fields = Vec::new();
@ -104,7 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
.as_local() .as_local()
.map(|local_def_id| hir_map.local_def_id_to_hir_id(local_def_id)); .map(|local_def_id| hir_map.local_def_id_to_hir_id(local_def_id));
if !is_lint_allowed(cx, NON_SEND_FIELDS_IN_SEND_TY, field_hir_id); if !is_lint_allowed(cx, NON_SEND_FIELDS_IN_SEND_TY, field_hir_id);
if let field_ty = field.ty(cx.tcx, impl_trait_substs); if let field_ty = field.ty(cx.tcx, impl_trait_args);
if !ty_allowed_in_send(cx, field_ty, send_trait); if !ty_allowed_in_send(cx, field_ty, send_trait);
if let Node::Field(field_def) = hir_map.get(field_hir_id); if let Node::Field(field_def) = hir_map.get(field_hir_id);
then { then {
@ -206,10 +206,10 @@ fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t
.iter() .iter()
.all(|ty| ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait)), .all(|ty| ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait)),
ty::Array(ty, _) | ty::Slice(ty) => ty_allowed_with_raw_pointer_heuristic(cx, *ty, send_trait), ty::Array(ty, _) | ty::Slice(ty) => ty_allowed_with_raw_pointer_heuristic(cx, *ty, send_trait),
ty::Adt(_, substs) => { ty::Adt(_, args) => {
if contains_pointer_like(cx, ty) { if contains_pointer_like(cx, ty) {
// descends only if ADT contains any raw pointers // descends only if ADT contains any raw pointers
substs.iter().all(|generic_arg| match generic_arg.unpack() { args.iter().all(|generic_arg| match generic_arg.unpack() {
GenericArgKind::Type(ty) => ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait), GenericArgKind::Type(ty) => ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait),
// Lifetimes and const generics are not solid part of ADT and ignored // Lifetimes and const generics are not solid part of ADT and ignored
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => true, GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => true,
@ -224,7 +224,7 @@ fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t
} }
} }
/// Checks if the type contains any pointer-like types in substs (including nested ones) /// Checks if the type contains any pointer-like types in args (including nested ones)
fn contains_pointer_like<'tcx>(cx: &LateContext<'tcx>, target_ty: Ty<'tcx>) -> bool { fn contains_pointer_like<'tcx>(cx: &LateContext<'tcx>, target_ty: Ty<'tcx>) -> bool {
for ty_node in target_ty.walk() { for ty_node in target_ty.walk() {
if let GenericArgKind::Type(inner_ty) = ty_node.unpack() { if let GenericArgKind::Type(inner_ty) = ty_node.unpack() {

View file

@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::hir_id::HirIdMap; use rustc_hir::hir_id::HirIdMap;
use rustc_hir::{Body, Expr, ExprKind, HirId, ImplItem, ImplItemKind, Node, PatKind, TraitItem, TraitItemKind}; use rustc_hir::{Body, Expr, ExprKind, HirId, ImplItem, ImplItemKind, Node, PatKind, TraitItem, TraitItemKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::subst::{EarlyBinder, GenericArgKind, SubstsRef}; use rustc_middle::ty::{EarlyBinder, GenericArgKind, GenericArgsRef};
use rustc_middle::ty::{self, ConstKind}; use rustc_middle::ty::{self, ConstKind};
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::symbol::{kw, Ident}; use rustc_span::symbol::{kw, Ident};
@ -90,7 +90,7 @@ impl_lint_pass!(OnlyUsedInRecursion => [ONLY_USED_IN_RECURSION]);
enum FnKind { enum FnKind {
Fn, Fn,
TraitFn, TraitFn,
// This is a hack. Ideally we would store a `SubstsRef<'tcx>` type here, but a lint pass must be `'static`. // This is a hack. Ideally we would store a `GenericArgsRef<'tcx>` type here, but a lint pass must be `'static`.
// Substitutions are, however, interned. This allows us to store the pointer as a `usize` when comparing for // Substitutions are, however, interned. This allows us to store the pointer as a `usize` when comparing for
// equality. // equality.
ImplTraitFn(usize), ImplTraitFn(usize),
@ -244,12 +244,12 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
})) => { })) => {
#[allow(trivial_casts)] #[allow(trivial_casts)]
if let Some(Node::Item(item)) = get_parent_node(cx.tcx, owner_id.into()) if let Some(Node::Item(item)) = get_parent_node(cx.tcx, owner_id.into())
&& let Some(trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(EarlyBinder::subst_identity) && let Some(trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(EarlyBinder::instantiate_identity)
&& let Some(trait_item_id) = cx.tcx.associated_item(owner_id).trait_item_def_id && let Some(trait_item_id) = cx.tcx.associated_item(owner_id).trait_item_def_id
{ {
( (
trait_item_id, trait_item_id,
FnKind::ImplTraitFn(cx.tcx.erase_regions(trait_ref.substs) as *const _ as usize), FnKind::ImplTraitFn(cx.tcx.erase_regions(trait_ref.args) as *const _ as usize),
usize::from(sig.decl.implicit_self.has_implicit_self()), usize::from(sig.decl.implicit_self.has_implicit_self()),
) )
} else { } else {
@ -289,7 +289,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
ExprKind::Call(callee, args) ExprKind::Call(callee, args)
if path_def_id(cx, callee).map_or(false, |id| { if path_def_id(cx, callee).map_or(false, |id| {
id == param.fn_id id == param.fn_id
&& has_matching_substs(param.fn_kind, typeck.node_substs(callee.hir_id)) && has_matching_args(param.fn_kind, typeck.node_args(callee.hir_id))
}) => }) =>
{ {
if let Some(idx) = args.iter().position(|arg| arg.hir_id == child_id) { if let Some(idx) = args.iter().position(|arg| arg.hir_id == child_id) {
@ -300,7 +300,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
ExprKind::MethodCall(_, receiver, args, _) ExprKind::MethodCall(_, receiver, args, _)
if typeck.type_dependent_def_id(parent.hir_id).map_or(false, |id| { if typeck.type_dependent_def_id(parent.hir_id).map_or(false, |id| {
id == param.fn_id id == param.fn_id
&& has_matching_substs(param.fn_kind, typeck.node_substs(parent.hir_id)) && has_matching_args(param.fn_kind, typeck.node_args(parent.hir_id))
}) => }) =>
{ {
if let Some(idx) = iter::once(receiver).chain(args).position(|arg| arg.hir_id == child_id) { if let Some(idx) = iter::once(receiver).chain(args).position(|arg| arg.hir_id == child_id) {
@ -381,15 +381,15 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
} }
} }
fn has_matching_substs(kind: FnKind, substs: SubstsRef<'_>) -> bool { fn has_matching_args(kind: FnKind, args: GenericArgsRef<'_>) -> bool {
match kind { match kind {
FnKind::Fn => true, FnKind::Fn => true,
FnKind::TraitFn => substs.iter().enumerate().all(|(idx, subst)| match subst.unpack() { FnKind::TraitFn => args.iter().enumerate().all(|(idx, subst)| match subst.unpack() {
GenericArgKind::Lifetime(_) => true, GenericArgKind::Lifetime(_) => true,
GenericArgKind::Type(ty) => matches!(*ty.kind(), ty::Param(ty) if ty.index as usize == idx), GenericArgKind::Type(ty) => matches!(*ty.kind(), ty::Param(ty) if ty.index as usize == idx),
GenericArgKind::Const(c) => matches!(c.kind(), ConstKind::Param(c) if c.index as usize == idx), GenericArgKind::Const(c) => matches!(c.kind(), ConstKind::Param(c) if c.index as usize == idx),
}), }),
#[allow(trivial_casts)] #[allow(trivial_casts)]
FnKind::ImplTraitFn(expected_substs) => substs as *const _ as usize == expected_substs, FnKind::ImplTraitFn(expected_args) => args as *const _ as usize == expected_args,
} }
} }

View file

@ -143,7 +143,7 @@ impl<'tcx> PassByRefOrValue {
return; return;
} }
let fn_sig = cx.tcx.fn_sig(def_id).subst_identity(); let fn_sig = cx.tcx.fn_sig(def_id).instantiate_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

View file

@ -166,7 +166,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).subst_identity().skip_binder().inputs(), cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder().inputs(),
sig.decl.inputs, sig.decl.inputs,
&sig.decl.output, &sig.decl.output,
&[], &[],
@ -220,7 +220,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).subst_identity().skip_binder(); let sig = cx.tcx.fn_sig(item_id).instantiate_identity().skip_binder();
let lint_args: Vec<_> = check_fn_args(cx, sig.inputs(), decl.inputs, &decl.output, body.params) let lint_args: Vec<_> = check_fn_args(cx, sig.inputs(), decl.inputs, &decl.output, body.params)
.filter(|arg| !is_trait_item || arg.mutability() == Mutability::Not) .filter(|arg| !is_trait_item || arg.mutability() == Mutability::Not)
.collect(); .collect();
@ -423,7 +423,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
.enumerate() .enumerate()
.filter_map(move |(i, (ty, hir_ty))| { .filter_map(move |(i, (ty, hir_ty))| {
if let ty::Ref(_, ty, mutability) = *ty.kind() if let ty::Ref(_, ty, mutability) = *ty.kind()
&& let ty::Adt(adt, substs) = *ty.kind() && let ty::Adt(adt, args) = *ty.kind()
&& let TyKind::Ref(lt, ref ty) = hir_ty.kind && let TyKind::Ref(lt, ref ty) = hir_ty.kind
&& let TyKind::Path(QPath::Resolved(None, path)) = ty.ty.kind && let TyKind::Path(QPath::Resolved(None, path)) = ty.ty.kind
// Check that the name as typed matches the actual name of the type. // Check that the name as typed matches the actual name of the type.
@ -443,7 +443,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
} else { } else {
None None
}), }),
substs.type_at(0), args.type_at(0),
), ),
), ),
_ if Some(adt.did()) == cx.tcx.lang_items().string() => ( _ if Some(adt.did()) == cx.tcx.lang_items().string() => (
@ -496,7 +496,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
} }
let ty_name = let ty_name =
snippet_opt(cx, ty.span()).unwrap_or_else(|| substs.type_at(1).to_string()); snippet_opt(cx, ty.span()).unwrap_or_else(|| args.type_at(1).to_string());
span_lint_hir_and_then( span_lint_hir_and_then(
cx, cx,
@ -659,7 +659,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
return; return;
}; };
match *self.cx.tcx.fn_sig(id).subst_identity().skip_binder().inputs()[i] match *self.cx.tcx.fn_sig(id).instantiate_identity().skip_binder().inputs()[i]
.peel_refs() .peel_refs()
.kind() .kind()
{ {
@ -725,7 +725,7 @@ fn matches_preds<'tcx>(
let infcx = cx.tcx.infer_ctxt().build(); let infcx = cx.tcx.infer_ctxt().build();
preds.iter().all(|&p| match cx.tcx.erase_late_bound_regions(p) { preds.iter().all(|&p| match cx.tcx.erase_late_bound_regions(p) {
ExistentialPredicate::Trait(p) => infcx ExistentialPredicate::Trait(p) => infcx
.type_implements_trait(p.def_id, [ty.into()].into_iter().chain(p.substs.iter()), cx.param_env) .type_implements_trait(p.def_id, [ty.into()].into_iter().chain(p.args.iter()), cx.param_env)
.must_apply_modulo_regions(), .must_apply_modulo_regions(),
ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new( ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new(
cx.tcx, cx.tcx,

View file

@ -9,7 +9,7 @@ use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
use rustc_lint::{LateContext, LateLintPass, Lint}; use rustc_lint::{LateContext, LateLintPass, Lint};
use rustc_middle::ty::Ty; use rustc_middle::ty::Ty;
use rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability};
use rustc_middle::ty::subst::GenericArg; use rustc_middle::ty::GenericArg;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
@ -135,7 +135,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
} else if let Some(target_id) = cx.tcx.lang_items().deref_target() { } else if let Some(target_id) = cx.tcx.lang_items().deref_target() {
if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions( if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions(
cx.param_env, cx.param_env,
Ty::new_projection(cx.tcx,target_id, cx.tcx.mk_substs(&[GenericArg::from(indexed_ty)])), Ty::new_projection(cx.tcx,target_id, cx.tcx.mk_args(&[GenericArg::from(indexed_ty)])),
) { ) {
if deref_ty == expr_ty { if deref_ty == expr_ty {
let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0; let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0;

View file

@ -9,7 +9,7 @@ use rustc_hir::intravisit::FnKind;
use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, 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::{self, subst::GenericArgKind, Ty}; use rustc_middle::ty::{self, GenericArgKind, 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::def_id::LocalDefId;
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
@ -333,7 +333,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() .instantiate_identity()
.skip_binder() .skip_binder()
.output() .output()
.walk() .walk()

View file

@ -53,7 +53,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).subst_identity(); let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity();
let ret_ty = return_ty(cx, impl_item.owner_id); let ret_ty = return_ty(cx, impl_item.owner_id);
// Do not check trait impls // Do not check trait impls

View file

@ -10,7 +10,7 @@ use rustc_hir::{
intravisit::{walk_expr, Visitor}, intravisit::{walk_expr, Visitor},
}; };
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::ty::{subst::GenericArgKind, Ty, TypeAndMut}; use rustc_middle::ty::{GenericArgKind, Ty, TypeAndMut};
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{symbol::Ident, Span, DUMMY_SP}; use rustc_span::{symbol::Ident, Span, DUMMY_SP};
use std::borrow::Cow; use std::borrow::Cow;

View file

@ -47,7 +47,7 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, inverted:
if let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id(); if let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id();
if matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::mem_size_of | sym::mem_size_of_val)); if matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::mem_size_of | sym::mem_size_of_val));
then { then {
cx.typeck_results().node_substs(count_func.hir_id).types().next() cx.typeck_results().node_args(count_func.hir_id).types().next()
} else { } else {
None None
} }
@ -101,7 +101,7 @@ fn get_pointee_ty_and_count_expr<'tcx>(
if FUNCTIONS.iter().any(|func_path| match_def_path(cx, def_id, func_path)); if FUNCTIONS.iter().any(|func_path| match_def_path(cx, def_id, func_path));
// Get the pointee type // Get the pointee type
if let Some(pointee_ty) = cx.typeck_results().node_substs(func.hir_id).types().next(); if let Some(pointee_ty) = cx.typeck_results().node_args(func.hir_id).types().next();
then { then {
return Some((pointee_ty, count)); return Some((pointee_ty, count));
} }

View file

@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::ty::is_c_void; use clippy_utils::ty::is_c_void;
use rustc_hir::Expr; use rustc_hir::Expr;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::SubstsRef; use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, IntTy, Ty, TypeAndMut, UintTy}; use rustc_middle::ty::{self, IntTy, Ty, TypeAndMut, UintTy};
#[expect(clippy::too_many_lines)] #[expect(clippy::too_many_lines)]
@ -268,12 +268,12 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
} }
ReducedTy::UnorderedFields(ty) ReducedTy::UnorderedFields(ty)
}, },
ty::Adt(def, substs) if def.is_struct() => { ty::Adt(def, args) if def.is_struct() => {
let mut iter = def let mut iter = def
.non_enum_variant() .non_enum_variant()
.fields .fields
.iter() .iter()
.map(|f| cx.tcx.type_of(f.did).subst(cx.tcx, substs)); .map(|f| cx.tcx.type_of(f.did).instantiate(cx.tcx, args));
let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else { let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else {
return ReducedTy::TypeErasure { raw_ptr_only: false }; return ReducedTy::TypeErasure { raw_ptr_only: false };
}; };
@ -322,7 +322,7 @@ fn is_size_pair(ty: Ty<'_>) -> bool {
} }
} }
fn same_except_params<'tcx>(subs1: SubstsRef<'tcx>, subs2: SubstsRef<'tcx>) -> bool { fn same_except_params<'tcx>(subs1: GenericArgsRef<'tcx>, subs2: GenericArgsRef<'tcx>) -> bool {
// TODO: check const parameters as well. Currently this will consider `Array<5>` the same as // TODO: check const parameters as well. Currently this will consider `Array<5>` the same as
// `Array<6>` // `Array<6>`
for (ty1, ty2) in subs1.types().zip(subs2.types()).filter(|(ty1, ty2)| ty1 != ty2) { for (ty1, ty2) in subs1.types().zip(subs2.types()).filter(|(ty1, ty2)| ty1 != ty2) {

View file

@ -10,7 +10,7 @@ use rustc_span::symbol::sym;
/// Returns `true` if it's triggered, otherwise returns `false`. /// Returns `true` if it's triggered, otherwise returns `false`.
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool { pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {
match (&from_ty.kind(), &to_ty.kind()) { match (&from_ty.kind(), &to_ty.kind()) {
(ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => { (ty::Adt(from_adt, from_args), ty::Adt(to_adt, to_args)) => {
if from_adt.did() != to_adt.did() { if from_adt.did() != to_adt.did() {
return false; return false;
} }
@ -28,9 +28,9 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty
) { ) {
return false; return false;
} }
if from_substs if from_args
.types() .types()
.zip(to_substs.types()) .zip(to_args.types())
.any(|(from_ty, to_ty)| is_layout_incompatible(cx, from_ty, to_ty)) .any(|(from_ty, to_ty)| is_layout_incompatible(cx, from_ty, to_ty))
{ {
span_lint( span_lint(

View file

@ -88,7 +88,7 @@ fn handle_uninit_vec_pair<'tcx>(
if let Some((set_len_self, call_span)) = extract_set_len_self(cx, maybe_set_len); if let Some((set_len_self, call_span)) = extract_set_len_self(cx, maybe_set_len);
if vec.location.eq_expr(cx, set_len_self); if vec.location.eq_expr(cx, set_len_self);
if let ty::Ref(_, vec_ty, _) = cx.typeck_results().expr_ty_adjusted(set_len_self).kind(); if let ty::Ref(_, vec_ty, _) = cx.typeck_results().expr_ty_adjusted(set_len_self).kind();
if let ty::Adt(_, substs) = vec_ty.kind(); if let ty::Adt(_, args) = vec_ty.kind();
// `#[allow(...)]` attribute can be set on enclosing unsafe block of `set_len()` // `#[allow(...)]` attribute can be set on enclosing unsafe block of `set_len()`
if !is_lint_allowed(cx, UNINIT_VEC, maybe_set_len.hir_id); if !is_lint_allowed(cx, UNINIT_VEC, maybe_set_len.hir_id);
then { then {
@ -96,7 +96,7 @@ fn handle_uninit_vec_pair<'tcx>(
// with_capacity / reserve -> set_len // with_capacity / reserve -> set_len
// Check T of Vec<T> // Check T of Vec<T>
if !is_uninit_value_valid_for_ty(cx, substs.type_at(0)) { if !is_uninit_value_valid_for_ty(cx, args.type_at(0)) {
// FIXME: #7698, false positive of the internal lints // FIXME: #7698, false positive of the internal lints
#[expect(clippy::collapsible_span_lint_calls)] #[expect(clippy::collapsible_span_lint_calls)]
span_lint_and_then( span_lint_and_then(

View file

@ -65,7 +65,7 @@ fn get_projection_pred<'tcx>(
generics.predicates.iter().find_map(|(proj_pred, _)| { generics.predicates.iter().find_map(|(proj_pred, _)| {
if let ClauseKind::Projection(pred) = proj_pred.kind().skip_binder() { if let ClauseKind::Projection(pred) = proj_pred.kind().skip_binder() {
let projection_pred = cx.tcx.erase_late_bound_regions(proj_pred.kind().rebind(pred)); let projection_pred = cx.tcx.erase_late_bound_regions(proj_pred.kind().rebind(pred));
if projection_pred.projection_ty.substs == trait_pred.trait_ref.substs { if projection_pred.projection_ty.args == trait_pred.trait_ref.args {
return Some(projection_pred); return Some(projection_pred);
} }
} }
@ -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).subst_identity(); let fn_sig = cx.tcx.fn_sig(def_id).instantiate_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));
@ -120,8 +120,8 @@ fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Ve
fn check_arg<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Option<(Span, Option<Span>)> { fn check_arg<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Option<(Span, Option<Span>)> {
if_chain! { if_chain! {
if let ExprKind::Closure(&Closure { body, fn_decl_span, .. }) = arg.kind; if let ExprKind::Closure(&Closure { body, fn_decl_span, .. }) = arg.kind;
if let ty::Closure(_def_id, substs) = &cx.typeck_results().node_type(arg.hir_id).kind(); if let ty::Closure(_def_id, args) = &cx.typeck_results().node_type(arg.hir_id).kind();
let ret_ty = substs.as_closure().sig().output(); let ret_ty = args.as_closure().sig().output();
let ty = cx.tcx.erase_late_bound_regions(ret_ty); let ty = cx.tcx.erase_late_bound_regions(ret_ty);
if ty.is_unit(); if ty.is_unit();
then { then {

View file

@ -161,7 +161,7 @@ fn needs_inferred_result_ty(
}, },
_ => return false, _ => return false,
}; };
let sig = cx.tcx.fn_sig(id).subst_identity().skip_binder(); let sig = cx.tcx.fn_sig(id).instantiate_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

@ -97,7 +97,7 @@ impl LateLintPass<'_> for UnnamedAddress {
if let ExprKind::Path(ref func_qpath) = func.kind; if let ExprKind::Path(ref func_qpath) = func.kind;
if let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id(); if let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id();
if match_def_path(cx, def_id, &paths::PTR_EQ); if match_def_path(cx, def_id, &paths::PTR_EQ);
let ty_param = cx.typeck_results().node_substs(func.hir_id).type_at(0); let ty_param = cx.typeck_results().node_args(func.hir_id).type_at(0);
if ty_param.is_trait(); if ty_param.is_trait();
then { then {
span_lint_and_help( span_lint_and_help(

View file

@ -145,7 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
then { then {
// `self_ty` is the semantic self type of `impl <trait> for <type>`. This cannot be // `self_ty` is the semantic self type of `impl <trait> for <type>`. This cannot be
// `Self`. // `Self`.
let self_ty = impl_trait_ref.subst_identity().self_ty(); let self_ty = impl_trait_ref.instantiate_identity().self_ty();
// `trait_method_sig` is the signature of the function, how it is declared in the // `trait_method_sig` is the signature of the function, how it is declared in the
// trait, not in the impl of the trait. // trait, not in the impl of the trait.
@ -154,7 +154,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).subst_identity(); let trait_method_sig = cx.tcx.fn_sig(trait_method).instantiate_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
@ -226,7 +226,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
} else { } else {
hir_ty_to_ty(cx.tcx, hir_ty) hir_ty_to_ty(cx.tcx, hir_ty)
}; };
if same_type_and_consts(ty, cx.tcx.type_of(impl_id).subst_identity()); if same_type_and_consts(ty, cx.tcx.type_of(impl_id).instantiate_identity());
then { then {
span_lint(cx, hir_ty.span); span_lint(cx, hir_ty.span);
} }
@ -238,7 +238,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
if !expr.span.from_expansion(); if !expr.span.from_expansion();
if self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS); if self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS);
if let Some(&StackItem::Check { impl_id, .. }) = self.stack.last(); if let Some(&StackItem::Check { impl_id, .. }) = self.stack.last();
if cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id).subst_identity(); if cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id).instantiate_identity();
then {} else { return; } then {} else { return; }
} }
match expr.kind { match expr.kind {
@ -262,7 +262,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
if let PatKind::Path(QPath::Resolved(_, path)) if let PatKind::Path(QPath::Resolved(_, path))
| PatKind::TupleStruct(QPath::Resolved(_, path), _, _) | PatKind::TupleStruct(QPath::Resolved(_, path), _, _)
| PatKind::Struct(QPath::Resolved(_, path), _, _) = pat.kind; | PatKind::Struct(QPath::Resolved(_, path), _, _) = pat.kind;
if cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id).subst_identity(); if cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id).instantiate_identity();
then { then {
check_path(cx, path); check_path(cx, path);
} }

View file

@ -227,8 +227,8 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
let a = cx.typeck_results().expr_ty(e); let a = cx.typeck_results().expr_ty(e);
let b = cx.typeck_results().expr_ty(recv); let b = cx.typeck_results().expr_ty(recv);
if is_type_diagnostic_item(cx, a, sym::Result); if is_type_diagnostic_item(cx, a, sym::Result);
if let ty::Adt(_, substs) = a.kind(); if let ty::Adt(_, args) = a.kind();
if let Some(a_type) = substs.types().next(); if let Some(a_type) = args.types().next();
if same_type_and_consts(a_type, b); if same_type_and_consts(a_type, b);
then { then {
@ -255,8 +255,8 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
if_chain! { if_chain! {
if match_def_path(cx, def_id, &paths::TRY_FROM); if match_def_path(cx, def_id, &paths::TRY_FROM);
if is_type_diagnostic_item(cx, a, sym::Result); if is_type_diagnostic_item(cx, a, sym::Result);
if let ty::Adt(_, substs) = a.kind(); if let ty::Adt(_, args) = a.kind();
if let Some(a_type) = substs.types().next(); if let Some(a_type) = args.types().next();
if same_type_and_consts(a_type, b); if same_type_and_consts(a_type, b);
then { then {

View file

@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
for item in cx.tcx.module_children(def_id) { for item in cx.tcx.module_children(def_id) {
if_chain! { if_chain! {
if let Res::Def(DefKind::Const, item_def_id) = item.res; if let Res::Def(DefKind::Const, item_def_id) = item.res;
let ty = cx.tcx.type_of(item_def_id).subst_identity(); let ty = cx.tcx.type_of(item_def_id).instantiate_identity();
if match_type(cx, ty, &paths::SYMBOL); if match_type(cx, ty, &paths::SYMBOL);
if let Ok(ConstValue::Scalar(value)) = cx.tcx.const_eval_poly(item_def_id); if let Ok(ConstValue::Scalar(value)) = cx.tcx.const_eval_poly(item_def_id);
if let Ok(value) = value.to_u32(); if let Ok(value) = value.to_u32();

View file

@ -7,7 +7,7 @@ use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir_analysis::hir_ty_to_ty; use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::ty::{self, subst::GenericArgKind}; use rustc_middle::ty::{self, GenericArgKind};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
@ -39,7 +39,7 @@ impl LateLintPass<'_> for MsrvAttrImpl {
if self_ty_def.all_fields().any(|f| { if self_ty_def.all_fields().any(|f| {
cx.tcx cx.tcx
.type_of(f.did) .type_of(f.did)
.subst_identity() .instantiate_identity()
.walk() .walk()
.filter(|t| matches!(t.unpack(), GenericArgKind::Type(_))) .filter(|t| matches!(t.unpack(), GenericArgKind::Type(_)))
.any(|t| match_type(cx, t.expect_ty(), &paths::MSRV)) .any(|t| match_type(cx, t.expect_ty(), &paths::MSRV))

View file

@ -229,11 +229,11 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
Res::Def(DefKind::Static(_), def_id) => read_mir_alloc_def_path( Res::Def(DefKind::Static(_), def_id) => read_mir_alloc_def_path(
cx, cx,
cx.tcx.eval_static_initializer(def_id).ok()?.inner(), cx.tcx.eval_static_initializer(def_id).ok()?.inner(),
cx.tcx.type_of(def_id).subst_identity(), cx.tcx.type_of(def_id).instantiate_identity(),
), ),
Res::Def(DefKind::Const, def_id) => match cx.tcx.const_eval_poly(def_id).ok()? { Res::Def(DefKind::Const, def_id) => match cx.tcx.const_eval_poly(def_id).ok()? {
ConstValue::ByRef { alloc, offset } if offset.bytes() == 0 => { ConstValue::ByRef { alloc, offset } if offset.bytes() == 0 => {
read_mir_alloc_def_path(cx, alloc.inner(), cx.tcx.type_of(def_id).subst_identity()) read_mir_alloc_def_path(cx, alloc.inner(), cx.tcx.type_of(def_id).instantiate_identity())
}, },
_ => None, _ => None,
}, },

View file

@ -230,8 +230,8 @@ fn size_of(cx: &LateContext<'_>, expr: &Expr<'_>) -> u64 {
/// Returns the item type of the vector (i.e., the `T` in `Vec<T>`). /// Returns the item type of the vector (i.e., the `T` in `Vec<T>`).
fn vec_type(ty: Ty<'_>) -> Ty<'_> { fn vec_type(ty: Ty<'_>) -> Ty<'_> {
if let ty::Adt(_, substs) = ty.kind() { if let ty::Adt(_, args) = ty.kind() {
substs.type_at(0) args.type_at(0)
} else { } else {
panic!("The type of `vec!` is a not a struct?"); panic!("The type of `vec!` is a not a struct?");
} }

View file

@ -51,8 +51,8 @@ impl LateLintPass<'_> for ZeroSizedMapValues {
if !in_trait_impl(cx, hir_ty.hir_id); if !in_trait_impl(cx, hir_ty.hir_id);
let ty = ty_from_hir_ty(cx, hir_ty); let ty = ty_from_hir_ty(cx, hir_ty);
if is_type_diagnostic_item(cx, ty, sym::HashMap) || is_type_diagnostic_item(cx, ty, sym::BTreeMap); if is_type_diagnostic_item(cx, ty, sym::HashMap) || is_type_diagnostic_item(cx, ty, sym::BTreeMap);
if let Adt(_, substs) = ty.kind(); if let Adt(_, args) = ty.kind();
let ty = substs.type_at(1); let ty = args.type_at(1);
// Fixes https://github.com/rust-lang/rust-clippy/issues/7447 because of // Fixes https://github.com/rust-lang/rust-clippy/issues/7447 because of
// https://github.com/rust-lang/rust/blob/master/compiler/rustc_middle/src/ty/sty.rs#L968 // https://github.com/rust-lang/rust/blob/master/compiler/rustc_middle/src/ty/sty.rs#L968
if !ty.has_escaping_bound_vars(); if !ty.has_escaping_bound_vars();

View file

@ -12,7 +12,7 @@ use rustc_lint::LateContext;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::interpret::Scalar;
use rustc_middle::ty::{self, EarlyBinder, FloatTy, ScalarInt, Ty, TyCtxt}; use rustc_middle::ty::{self, EarlyBinder, FloatTy, ScalarInt, Ty, TyCtxt};
use rustc_middle::ty::{List, SubstsRef}; use rustc_middle::ty::{List, GenericArgsRef};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_span::symbol::{Ident, Symbol}; use rustc_span::symbol::{Ident, Symbol};
use rustc_span::SyntaxContext; use rustc_span::SyntaxContext;
@ -327,7 +327,7 @@ pub struct ConstEvalLateContext<'a, 'tcx> {
typeck_results: &'a ty::TypeckResults<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
source: ConstantSource, source: ConstantSource,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
} }
impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
@ -337,7 +337,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
typeck_results, typeck_results,
param_env: lcx.param_env, param_env: lcx.param_env,
source: ConstantSource::Local, source: ConstantSource::Local,
substs: List::empty(), args: List::empty(),
} }
} }
@ -473,16 +473,16 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
return None; return None;
} }
let substs = self.typeck_results.node_substs(id); let args = self.typeck_results.node_args(id);
let substs = if self.substs.is_empty() { let args = if self.args.is_empty() {
substs args
} else { } else {
EarlyBinder::bind(substs).subst(self.lcx.tcx, self.substs) EarlyBinder::bind(args).instantiate(self.lcx.tcx, self.args)
}; };
let result = self let result = self
.lcx .lcx
.tcx .tcx
.const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, substs), None) .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), None)
.ok() .ok()
.map(|val| rustc_middle::mir::ConstantKind::from_value(val, ty))?; .map(|val| rustc_middle::mir::ConstantKind::from_value(val, ty))?;
let result = miri_to_const(self.lcx, result)?; let result = miri_to_const(self.lcx, result)?;

View file

@ -51,7 +51,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg:
let name = name.as_str(); let name = name.as_str();
let ty = match cx.tcx.impl_of_method(fn_id) { let ty = match cx.tcx.impl_of_method(fn_id) {
Some(id) => cx.tcx.type_of(id).subst_identity(), Some(id) => cx.tcx.type_of(id).instantiate_identity(),
None => return Lazy, None => return Lazy,
}; };
@ -72,7 +72,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg:
.variants() .variants()
.iter() .iter()
.flat_map(|v| v.fields.iter()) .flat_map(|v| v.fields.iter())
.any(|x| matches!(cx.tcx.type_of(x.did).subst_identity().peel_refs().kind(), ty::Param(_))) .any(|x| matches!(cx.tcx.type_of(x.did).instantiate_identity().peel_refs().kind(), ty::Param(_)))
&& all_predicates_of(cx.tcx, fn_id).all(|(pred, _)| match pred.kind().skip_binder() { && all_predicates_of(cx.tcx, fn_id).all(|(pred, _)| match pred.kind().skip_binder() {
ty::ClauseKind::Trait(pred) => cx.tcx.trait_def(pred.trait_ref.def_id).is_marker, ty::ClauseKind::Trait(pred) => cx.tcx.trait_def(pred.trait_ref.def_id).is_marker,
_ => true, _ => true,
@ -80,7 +80,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).subst_identity().skip_binder().inputs_and_output { match &**cx.tcx.fn_sig(fn_id).instantiate_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

@ -305,7 +305,7 @@ pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str])
/// Checks if a method is defined in an impl of a diagnostic item /// Checks if a method is defined in an impl of a diagnostic item
pub fn is_diag_item_method(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol) -> bool { pub fn is_diag_item_method(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol) -> bool {
if let Some(impl_did) = cx.tcx.impl_of_method(def_id) { if let Some(impl_did) = cx.tcx.impl_of_method(def_id) {
if let Some(adt) = cx.tcx.type_of(impl_did).subst_identity().ty_adt_def() { if let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def() {
return cx.tcx.is_diagnostic_item(diag_item, adt.did()); return cx.tcx.is_diagnostic_item(diag_item, adt.did());
} }
} }
@ -812,7 +812,7 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<
if let QPath::TypeRelative(_, method) = path { if let QPath::TypeRelative(_, method) = path {
if method.ident.name == sym::new { if method.ident.name == sym::new {
if let Some(impl_did) = cx.tcx.impl_of_method(def_id) { if let Some(impl_did) = cx.tcx.impl_of_method(def_id) {
if let Some(adt) = cx.tcx.type_of(impl_did).subst_identity().ty_adt_def() { if let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def() {
return std_types_symbols.iter().any(|&symbol| { return std_types_symbols.iter().any(|&symbol| {
cx.tcx.is_diagnostic_item(symbol, adt.did()) || Some(adt.did()) == cx.tcx.lang_items().string() cx.tcx.is_diagnostic_item(symbol, adt.did()) || Some(adt.did()) == cx.tcx.lang_items().string()
}); });
@ -1377,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).subst_identity().skip_binder().inputs()[i]; let ty = cx.tcx.fn_sig(id).instantiate_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,
@ -1639,13 +1639,13 @@ 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_def_id: hir::OwnerId) -> Ty<'tcx> { pub fn return_ty<'tcx>(cx: &LateContext<'tcx>, fn_def_id: hir::OwnerId) -> Ty<'tcx> {
let ret_ty = cx.tcx.fn_sig(fn_def_id).subst_identity().output(); let ret_ty = cx.tcx.fn_sig(fn_def_id).instantiate_identity().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_def_id: hir::OwnerId, nth: usize) -> Ty<'tcx> { pub fn nth_arg<'tcx>(cx: &LateContext<'tcx>, fn_def_id: hir::OwnerId, nth: usize) -> Ty<'tcx> {
let arg = cx.tcx.fn_sig(fn_def_id).subst_identity().input(nth); let arg = cx.tcx.fn_sig(fn_def_id).instantiate_identity().input(nth);
cx.tcx.erase_late_bound_regions(arg) cx.tcx.erase_late_bound_regions(arg)
} }

View file

@ -15,7 +15,7 @@ use rustc_middle::mir::{
Terminator, TerminatorKind, Terminator, TerminatorKind,
}; };
use rustc_middle::traits::{ImplSource, ObligationCause}; use rustc_middle::traits::{ImplSource, ObligationCause};
use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::GenericArgKind;
use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt}; use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt};
use rustc_middle::ty::{BoundConstness, TraitRef}; use rustc_middle::ty::{BoundConstness, TraitRef};
use rustc_semver::RustcVersion; use rustc_semver::RustcVersion;
@ -35,7 +35,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).subst_identity().output().skip_binder(), tcx.fn_sig(def_id).instantiate_identity().output().skip_binder(),
body.local_decls.iter().next().unwrap().source_info.span, body.local_decls.iter().next().unwrap().source_info.span,
)?; )?;

View file

@ -877,7 +877,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).subst_identity().skip_binder()) .map(|did| self.cx.tcx.fn_sig(did).instantiate_identity().skip_binder())
{ {
std::iter::once(receiver) std::iter::once(receiver)
.chain(call_args.iter()) .chain(call_args.iter())

View file

@ -17,7 +17,7 @@ use rustc_lint::LateContext;
use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::mir::interpret::{ConstValue, Scalar};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, layout::ValidityRequirement, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, IntTy, List, ParamEnv, self, layout::ValidityRequirement, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, IntTy, List, ParamEnv,
Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, Region, RegionKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
UintTy, VariantDef, VariantDiscr, UintTy, VariantDef, VariantDiscr,
}; };
use rustc_middle::ty::{GenericArg, GenericArgKind}; use rustc_middle::ty::{GenericArg, GenericArgKind};
@ -90,14 +90,14 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
return false; return false;
} }
for (predicate, _span) in cx.tcx.explicit_item_bounds(def_id).subst_identity_iter_copied() { for (predicate, _span) in cx.tcx.explicit_item_bounds(def_id).instantiate_identity_iter_copied() {
match predicate.kind().skip_binder() { match predicate.kind().skip_binder() {
// For `impl Trait<U>`, it will register a predicate of `T: Trait<U>`, so we go through // For `impl Trait<U>`, it will register a predicate of `T: Trait<U>`, so we go through
// and check substitutions to find `U`. // and check substitutions to find `U`.
ty::ClauseKind::Trait(trait_predicate) => { ty::ClauseKind::Trait(trait_predicate) => {
if trait_predicate if trait_predicate
.trait_ref .trait_ref
.substs .args
.types() .types()
.skip(1) // Skip the implicit `Self` generic parameter .skip(1) // Skip the implicit `Self` generic parameter
.any(|ty| contains_ty_adt_constructor_opaque_inner(cx, ty, needle, seen)) .any(|ty| contains_ty_adt_constructor_opaque_inner(cx, ty, needle, seen))
@ -237,7 +237,7 @@ pub fn implements_trait_with_env<'tcx>(
kind: TypeVariableOriginKind::MiscVariable, kind: TypeVariableOriginKind::MiscVariable,
span: DUMMY_SP, span: DUMMY_SP,
}; };
let ty_params = tcx.mk_substs_from_iter( let ty_params = tcx.mk_args_from_iter(
ty_params ty_params
.into_iter() .into_iter()
.map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(orig).into())), .map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(orig).into())),
@ -265,7 +265,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
// because we don't want to lint functions returning empty arrays // because we don't want to lint functions returning empty arrays
is_must_use_ty(cx, *ty) is_must_use_ty(cx, *ty)
}, },
ty::Tuple(substs) => substs.iter().any(|ty| is_must_use_ty(cx, ty)), ty::Tuple(args) => args.iter().any(|ty| is_must_use_ty(cx, ty)),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
for (predicate, _) in cx.tcx.explicit_item_bounds(def_id).skip_binder() { for (predicate, _) in cx.tcx.explicit_item_bounds(def_id).skip_binder() {
if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() { if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() {
@ -314,11 +314,11 @@ fn is_normalizable_helper<'tcx>(
let cause = rustc_middle::traits::ObligationCause::dummy(); let cause = rustc_middle::traits::ObligationCause::dummy();
let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() { let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() {
match ty.kind() { match ty.kind() {
ty::Adt(def, substs) => def.variants().iter().all(|variant| { ty::Adt(def, args) => def.variants().iter().all(|variant| {
variant variant
.fields .fields
.iter() .iter()
.all(|field| is_normalizable_helper(cx, param_env, field.ty(cx.tcx, substs), cache)) .all(|field| is_normalizable_helper(cx, param_env, field.ty(cx.tcx, args), cache))
}), }),
_ => ty.walk().all(|generic_arg| match generic_arg.unpack() { _ => ty.walk().all(|generic_arg| match generic_arg.unpack() {
GenericArgKind::Type(inner_ty) if inner_ty != ty => { GenericArgKind::Type(inner_ty) if inner_ty != ty => {
@ -517,14 +517,14 @@ pub fn walk_ptrs_ty_depth(ty: Ty<'_>) -> (Ty<'_>, usize) {
/// otherwise returns `false` /// otherwise returns `false`
pub fn same_type_and_consts<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool { pub fn same_type_and_consts<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
match (&a.kind(), &b.kind()) { match (&a.kind(), &b.kind()) {
(&ty::Adt(did_a, substs_a), &ty::Adt(did_b, substs_b)) => { (&ty::Adt(did_a, args_a), &ty::Adt(did_b, args_b)) => {
if did_a != did_b { if did_a != did_b {
return false; return false;
} }
substs_a args_a
.iter() .iter()
.zip(substs_b.iter()) .zip(args_b.iter())
.all(|(arg_a, arg_b)| match (arg_a.unpack(), arg_b.unpack()) { .all(|(arg_a, arg_b)| match (arg_a.unpack(), arg_b.unpack()) {
(GenericArgKind::Const(inner_a), GenericArgKind::Const(inner_b)) => inner_a == inner_b, (GenericArgKind::Const(inner_a), GenericArgKind::Const(inner_b)) => inner_a == inner_b,
(GenericArgKind::Type(type_a), GenericArgKind::Type(type_b)) => { (GenericArgKind::Type(type_a), GenericArgKind::Type(type_b)) => {
@ -643,7 +643,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).subst_identity(), Some(id))) Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate_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())
} }
@ -661,11 +661,11 @@ 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.fn_sig(id).subst(cx.tcx, subs), Some(id))), ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate(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, args, .. }) => sig_from_bounds(
cx, cx,
ty, ty,
cx.tcx.item_bounds(def_id).subst_iter(cx.tcx, substs), cx.tcx.item_bounds(def_id).arg_iter(cx.tcx, args),
cx.tcx.opt_parent(def_id), cx.tcx.opt_parent(def_id),
), ),
ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)), ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)),
@ -681,7 +681,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
.projection_bounds() .projection_bounds()
.find(|p| lang_items.fn_once_output().map_or(false, |id| id == p.item_def_id())) .find(|p| lang_items.fn_once_output().map_or(false, |id| id == p.item_def_id()))
.map(|p| p.map_bound(|p| p.term.ty().unwrap())); .map(|p| p.map_bound(|p| p.term.ty().unwrap()));
Some(ExprFnSig::Trait(bound.map_bound(|b| b.substs.type_at(0)), output, None)) Some(ExprFnSig::Trait(bound.map_bound(|b| b.args.type_at(0)), output, None))
}, },
_ => None, _ => None,
} }
@ -713,7 +713,7 @@ fn sig_from_bounds<'tcx>(
|| lang_items.fn_once_trait() == Some(p.def_id())) || lang_items.fn_once_trait() == Some(p.def_id()))
&& p.self_ty() == ty => && p.self_ty() == ty =>
{ {
let i = pred.kind().rebind(p.trait_ref.substs.type_at(1)); let i = pred.kind().rebind(p.trait_ref.args.type_at(1));
if inputs.map_or(false, |inputs| i != inputs) { if inputs.map_or(false, |inputs| i != inputs) {
// Multiple different fn trait impls. Is this even allowed? // Multiple different fn trait impls. Is this even allowed?
return None; return None;
@ -744,7 +744,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option
for (pred, _) in cx for (pred, _) in cx
.tcx .tcx
.explicit_item_bounds(ty.def_id) .explicit_item_bounds(ty.def_id)
.subst_iter_copied(cx.tcx, ty.substs) .arg_iter_copied(cx.tcx, ty.args)
{ {
match pred.kind().skip_binder() { match pred.kind().skip_binder() {
ty::ClauseKind::Trait(p) ty::ClauseKind::Trait(p)
@ -752,7 +752,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option
|| lang_items.fn_mut_trait() == Some(p.def_id()) || lang_items.fn_mut_trait() == Some(p.def_id())
|| lang_items.fn_once_trait() == Some(p.def_id())) => || lang_items.fn_once_trait() == Some(p.def_id())) =>
{ {
let i = pred.kind().rebind(p.trait_ref.substs.type_at(1)); let i = pred.kind().rebind(p.trait_ref.args.type_at(1));
if inputs.map_or(false, |inputs| inputs != i) { if inputs.map_or(false, |inputs| inputs != i) {
// Multiple different fn trait impls. Is this even allowed? // Multiple different fn trait impls. Is this even allowed?
@ -793,7 +793,7 @@ impl core::ops::Add<u32> for EnumValue {
#[expect(clippy::cast_possible_truncation, clippy::cast_possible_wrap)] #[expect(clippy::cast_possible_truncation, clippy::cast_possible_wrap)]
pub fn read_explicit_enum_value(tcx: TyCtxt<'_>, id: DefId) -> Option<EnumValue> { pub fn read_explicit_enum_value(tcx: TyCtxt<'_>, id: DefId) -> Option<EnumValue> {
if let Ok(ConstValue::Scalar(Scalar::Int(value))) = tcx.const_eval_poly(id) { if let Ok(ConstValue::Scalar(Scalar::Int(value))) = tcx.const_eval_poly(id) {
match tcx.type_of(id).subst_identity().kind() { match tcx.type_of(id).instantiate_identity().kind() {
ty::Int(_) => Some(EnumValue::Signed(match value.size().bytes() { ty::Int(_) => Some(EnumValue::Signed(match value.size().bytes() {
1 => i128::from(value.assert_bits(Size::from_bytes(1)) as u8 as i8), 1 => i128::from(value.assert_bits(Size::from_bytes(1)) as u8 as i8),
2 => i128::from(value.assert_bits(Size::from_bytes(2)) as u16 as i16), 2 => i128::from(value.assert_bits(Size::from_bytes(2)) as u16 as i16),
@ -927,7 +927,7 @@ pub fn adt_and_variant_of_res<'tcx>(cx: &LateContext<'tcx>, res: Res) -> Option<
Some((adt, adt.variant_with_id(var_id))) Some((adt, adt.variant_with_id(var_id)))
}, },
Res::SelfCtor(id) => { Res::SelfCtor(id) => {
let adt = cx.tcx.type_of(id).subst_identity().ty_adt_def().unwrap(); let adt = cx.tcx.type_of(id).instantiate_identity().ty_adt_def().unwrap();
Some((adt, adt.non_enum_variant())) Some((adt, adt.non_enum_variant()))
}, },
_ => None, _ => None,
@ -1025,13 +1025,13 @@ pub fn make_projection<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
container_id: DefId, container_id: DefId,
assoc_ty: Symbol, assoc_ty: Symbol,
substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, args: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
) -> Option<AliasTy<'tcx>> { ) -> Option<AliasTy<'tcx>> {
fn helper<'tcx>( fn helper<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
container_id: DefId, container_id: DefId,
assoc_ty: Symbol, assoc_ty: Symbol,
substs: SubstsRef<'tcx>, args: GenericArgsRef<'tcx>,
) -> Option<AliasTy<'tcx>> { ) -> Option<AliasTy<'tcx>> {
let Some(assoc_item) = tcx let Some(assoc_item) = tcx
.associated_items(container_id) .associated_items(container_id)
@ -1052,18 +1052,18 @@ pub fn make_projection<'tcx>(
.map(|x| &x.kind); .map(|x| &x.kind);
debug_assert!( debug_assert!(
generic_count == substs.len(), generic_count == args.len(),
"wrong number of substs for `{:?}`: found `{}` expected `{generic_count}`.\n\ "wrong number of args for `{:?}`: found `{}` expected `{generic_count}`.\n\
note: the expected parameters are: {:#?}\n\ note: the expected parameters are: {:#?}\n\
the given arguments are: `{substs:#?}`", the given arguments are: `{args:#?}`",
assoc_item.def_id, assoc_item.def_id,
substs.len(), args.len(),
params.map(ty::GenericParamDefKind::descr).collect::<Vec<_>>(), params.map(ty::GenericParamDefKind::descr).collect::<Vec<_>>(),
); );
if let Some((idx, (param, arg))) = params if let Some((idx, (param, arg))) = params
.clone() .clone()
.zip(substs.iter().map(GenericArg::unpack)) .zip(args.iter().map(GenericArg::unpack))
.enumerate() .enumerate()
.find(|(_, (param, arg))| { .find(|(_, (param, arg))| {
!matches!( !matches!(
@ -1078,20 +1078,20 @@ pub fn make_projection<'tcx>(
false, false,
"mismatched subst type at index {idx}: expected a {}, found `{arg:?}`\n\ "mismatched subst type at index {idx}: expected a {}, found `{arg:?}`\n\
note: the expected parameters are {:#?}\n\ note: the expected parameters are {:#?}\n\
the given arguments are {substs:#?}", the given arguments are {args:#?}",
param.descr(), param.descr(),
params.map(ty::GenericParamDefKind::descr).collect::<Vec<_>>() params.map(ty::GenericParamDefKind::descr).collect::<Vec<_>>()
); );
} }
} }
Some(tcx.mk_alias_ty(assoc_item.def_id, substs)) Some(tcx.mk_alias_ty(assoc_item.def_id, args))
} }
helper( helper(
tcx, tcx,
container_id, container_id,
assoc_ty, assoc_ty,
tcx.mk_substs_from_iter(substs.into_iter().map(Into::into)), tcx.mk_args_from_iter(args.into_iter().map(Into::into)),
) )
} }
@ -1106,25 +1106,25 @@ pub fn make_normalized_projection<'tcx>(
param_env: ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
container_id: DefId, container_id: DefId,
assoc_ty: Symbol, assoc_ty: Symbol,
substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, args: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
) -> Option<Ty<'tcx>> { ) -> Option<Ty<'tcx>> {
fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>) -> Option<Ty<'tcx>> { fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>) -> Option<Ty<'tcx>> {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
if let Some((i, subst)) = ty if let Some((i, subst)) = ty
.substs .args
.iter() .iter()
.enumerate() .enumerate()
.find(|(_, subst)| subst.has_late_bound_regions()) .find(|(_, subst)| subst.has_late_bound_regions())
{ {
debug_assert!( debug_assert!(
false, false,
"substs contain late-bound region at index `{i}` which can't be normalized.\n\ "args contain late-bound region at index `{i}` which can't be normalized.\n\
use `TyCtxt::erase_late_bound_regions`\n\ use `TyCtxt::erase_late_bound_regions`\n\
note: subst is `{subst:#?}`", note: subst is `{subst:#?}`",
); );
return None; return None;
} }
match tcx.try_normalize_erasing_regions(param_env, Ty::new_projection(tcx,ty.def_id, ty.substs)) { match tcx.try_normalize_erasing_regions(param_env, Ty::new_projection(tcx,ty.def_id, ty.args)) {
Ok(ty) => Some(ty), Ok(ty) => Some(ty),
Err(e) => { Err(e) => {
debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}"); debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}");
@ -1132,7 +1132,7 @@ pub fn make_normalized_projection<'tcx>(
}, },
} }
} }
helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, substs)?) helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, args)?)
} }
/// Check if given type has inner mutability such as [`std::cell::Cell`] or [`std::cell::RefCell`] /// Check if given type has inner mutability such as [`std::cell::Cell`] or [`std::cell::RefCell`]
@ -1147,7 +1147,7 @@ pub fn is_interior_mut_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
&& is_interior_mut_ty(cx, inner_ty) && is_interior_mut_ty(cx, inner_ty)
}, },
ty::Tuple(fields) => fields.iter().any(|ty| is_interior_mut_ty(cx, ty)), ty::Tuple(fields) => fields.iter().any(|ty| is_interior_mut_ty(cx, ty)),
ty::Adt(def, substs) => { ty::Adt(def, args) => {
// Special case for collections in `std` who's impl of `Hash` or `Ord` delegates to // Special case for collections in `std` who's impl of `Hash` or `Ord` delegates to
// that of their type parameters. Note: we don't include `HashSet` and `HashMap` // that of their type parameters. Note: we don't include `HashSet` and `HashMap`
// because they have no impl for `Hash` or `Ord`. // because they have no impl for `Hash` or `Ord`.
@ -1168,7 +1168,7 @@ pub fn is_interior_mut_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
let is_box = Some(def_id) == cx.tcx.lang_items().owned_box(); let is_box = Some(def_id) == cx.tcx.lang_items().owned_box();
if is_std_collection || is_box { if is_std_collection || is_box {
// The type is mutable if any of its type parameters are // The type is mutable if any of its type parameters are
substs.types().any(|ty| is_interior_mut_ty(cx, ty)) args.types().any(|ty| is_interior_mut_ty(cx, ty))
} else { } else {
!ty.has_escaping_bound_vars() !ty.has_escaping_bound_vars()
&& cx.tcx.layout_of(cx.param_env.and(ty)).is_ok() && cx.tcx.layout_of(cx.param_env.and(ty)).is_ok()
@ -1184,19 +1184,19 @@ pub fn make_normalized_projection_with_regions<'tcx>(
param_env: ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
container_id: DefId, container_id: DefId,
assoc_ty: Symbol, assoc_ty: Symbol,
substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, args: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
) -> Option<Ty<'tcx>> { ) -> Option<Ty<'tcx>> {
fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>) -> Option<Ty<'tcx>> { fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>) -> Option<Ty<'tcx>> {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
if let Some((i, subst)) = ty if let Some((i, subst)) = ty
.substs .args
.iter() .iter()
.enumerate() .enumerate()
.find(|(_, subst)| subst.has_late_bound_regions()) .find(|(_, subst)| subst.has_late_bound_regions())
{ {
debug_assert!( debug_assert!(
false, false,
"substs contain late-bound region at index `{i}` which can't be normalized.\n\ "args contain late-bound region at index `{i}` which can't be normalized.\n\
use `TyCtxt::erase_late_bound_regions`\n\ use `TyCtxt::erase_late_bound_regions`\n\
note: subst is `{subst:#?}`", note: subst is `{subst:#?}`",
); );
@ -1207,7 +1207,7 @@ pub fn make_normalized_projection_with_regions<'tcx>(
.infer_ctxt() .infer_ctxt()
.build() .build()
.at(&cause, param_env) .at(&cause, param_env)
.query_normalize(Ty::new_projection(tcx,ty.def_id, ty.substs)) .query_normalize(Ty::new_projection(tcx,ty.def_id, ty.args))
{ {
Ok(ty) => Some(ty.value), Ok(ty) => Some(ty.value),
Err(e) => { Err(e) => {
@ -1216,7 +1216,7 @@ pub fn make_normalized_projection_with_regions<'tcx>(
}, },
} }
} }
helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, substs)?) helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, args)?)
} }
pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {

View file

@ -1,5 +1,5 @@
// originally from rustc ./tests/ui/regions/issue-78262.rs // originally from rustc ./tests/ui/regions/issue-78262.rs
// ICE: to get the signature of a closure, use substs.as_closure().sig() not fn_sig() // ICE: to get the signature of a closure, use args.as_closure().sig() not fn_sig()
#![allow(clippy::upper_case_acronyms)] #![allow(clippy::upper_case_acronyms)]
trait TT {} trait TT {}

View file

@ -331,7 +331,7 @@ impl dyn TestTrait + '_ {
} }
// https://github.com/rust-lang/rust-clippy/issues/7746 // https://github.com/rust-lang/rust-clippy/issues/7746
fn angle_brackets_and_substs() { fn angle_brackets_and_args() {
let array_opt: Option<&[u8; 3]> = Some(&[4, 8, 7]); let array_opt: Option<&[u8; 3]> = Some(&[4, 8, 7]);
array_opt.map(<[u8; 3]>::as_slice); array_opt.map(<[u8; 3]>::as_slice);

View file

@ -331,7 +331,7 @@ impl dyn TestTrait + '_ {
} }
// https://github.com/rust-lang/rust-clippy/issues/7746 // https://github.com/rust-lang/rust-clippy/issues/7746
fn angle_brackets_and_substs() { fn angle_brackets_and_args() {
let array_opt: Option<&[u8; 3]> = Some(&[4, 8, 7]); let array_opt: Option<&[u8; 3]> = Some(&[4, 8, 7]);
array_opt.map(|a| a.as_slice()); array_opt.map(|a| a.as_slice());