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

Rustup

r? `@ghost`

changelog: none
This commit is contained in:
bors 2022-02-24 18:37:57 +00:00
commit 7b2896a8fc
50 changed files with 143 additions and 137 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "clippy"
version = "0.1.60"
version = "0.1.61"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"

View File

@ -1,6 +1,6 @@
[package]
name = "clippy_lints"
version = "0.1.60"
version = "0.1.61"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"

View File

@ -47,7 +47,7 @@ fn check_case_sensitive_file_extension_comparison(ctx: &LateContext<'_>, expr: &
then {
let mut ty = ctx.typeck_results().expr_ty(obj);
ty = match ty.kind() {
ty::Ref(_, ty, ..) => ty,
ty::Ref(_, ty, ..) => *ty,
_ => ty
};

View File

@ -123,7 +123,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
if let Some(fn_sig) = fn_sig_opt(self.cx, func.hir_id) {
for (expr, bound) in iter::zip(*args, fn_sig.skip_binder().inputs()) {
// Push found arg type, then visit arg.
self.ty_bounds.push(TyBound::Ty(bound));
self.ty_bounds.push(TyBound::Ty(*bound));
self.visit_expr(expr);
self.ty_bounds.pop();
}
@ -135,7 +135,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
if let Some(def_id) = self.cx.typeck_results().type_dependent_def_id(expr.hir_id) {
let fn_sig = self.cx.tcx.fn_sig(def_id).skip_binder();
for (expr, bound) in iter::zip(*args, fn_sig.inputs()) {
self.ty_bounds.push(TyBound::Ty(bound));
self.ty_bounds.push(TyBound::Ty(*bound));
self.visit_expr(expr);
self.ty_bounds.pop();
}
@ -210,7 +210,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, '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)?;
// We can't use `TyS::fn_sig` because it automatically performs substs, this may result in FNs.
// We can't use `Ty::fn_sig` because it automatically performs substs, this may result in FNs.
match node_ty.kind() {
ty::FnDef(def_id, _) => Some(cx.tcx.fn_sig(*def_id)),
ty::FnPtr(fn_sig) => Some(*fn_sig),

View File

@ -6,11 +6,9 @@ use clippy_utils::ty::{implements_trait, is_copy};
use clippy_utils::{ast_utils::is_useless_with_eq_exprs, eq_expr_value, is_in_test_function};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{
def::Res, def_id::DefId, BinOpKind, BorrowKind, Expr, ExprKind, GenericArg, ItemKind, QPath, Ty, TyKind,
};
use rustc_hir::{def::Res, def_id::DefId, BinOpKind, BorrowKind, Expr, ExprKind, GenericArg, ItemKind, QPath, TyKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, TyS};
use rustc_middle::ty::{self, Ty};
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
@ -279,7 +277,11 @@ impl<'tcx> LateLintPass<'tcx> for EqOp {
}
}
fn in_impl<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, bin_op: DefId) -> Option<(&'tcx Ty<'tcx>, &'tcx Ty<'tcx>)> {
fn in_impl<'tcx>(
cx: &LateContext<'tcx>,
e: &'tcx Expr<'_>,
bin_op: DefId,
) -> Option<(&'tcx rustc_hir::Ty<'tcx>, &'tcx rustc_hir::Ty<'tcx>)> {
if_chain! {
if let Some(block) = get_enclosing_block(cx, e.hir_id);
if let Some(impl_def_id) = cx.tcx.impl_of_method(block.hir_id.owner.to_def_id());
@ -301,7 +303,7 @@ fn in_impl<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, bin_op: DefId) -> Op
}
}
fn are_equal<'tcx>(cx: &LateContext<'tcx>, middle_ty: &TyS<'_>, hir_ty: &Ty<'_>) -> bool {
fn are_equal<'tcx>(cx: &LateContext<'tcx>, middle_ty: Ty<'_>, hir_ty: &rustc_hir::Ty<'_>) -> bool {
if_chain! {
if let ty::Adt(adt_def, _) = middle_ty.kind();
if let Some(local_did) = adt_def.did.as_local();

View File

@ -191,7 +191,7 @@ where
if overloaded_deref.is_some() {
n_needed = n_total;
}
ty = target;
ty = *target;
} else {
return (n_needed, ty);
}

View File

@ -193,7 +193,7 @@ fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span, tys: &m
|| KNOWN_WRAPPER_TYS.iter().any(|path| match_def_path(cx, adt.did, path))
&& substs.types().any(|ty| is_mutable_ty(cx, ty, span, tys))
},
ty::Tuple(substs) => substs.types().any(|ty| is_mutable_ty(cx, ty, span, tys)),
ty::Tuple(substs) => substs.iter().any(|ty| is_mutable_ty(cx, ty, span, tys)),
ty::Array(ty, _) | ty::Slice(ty) => is_mutable_ty(cx, ty, span, tys),
ty::RawPtr(ty::TypeAndMut { ty, mutbl }) | ty::Ref(_, ty, mutbl) => {
mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, span, tys)

View File

@ -118,7 +118,7 @@ fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap<hir
// The values need to use the `ref` keyword if they can't be copied.
// This will need to be adjusted if the lint want to support multable access in the future
let src_is_ref = bound_ty.is_ref() && binding != hir::BindingAnnotation::Ref;
let needs_ref = !(src_is_ref || is_copy(cx, inner_ty));
let needs_ref = !(src_is_ref || is_copy(cx, *inner_ty));
let slice_info = slices
.entry(value_hir_id)

View File

@ -53,9 +53,9 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
if let ItemKind::Const(hir_ty, _) = &item.kind;
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
if let ty::Array(element_type, cst) = ty.kind();
if let ConstKind::Value(ConstValue::Scalar(element_count)) = cst.val;
if let ConstKind::Value(ConstValue::Scalar(element_count)) = cst.val();
if let Ok(element_count) = element_count.to_machine_usize(&cx.tcx);
if let Ok(element_size) = cx.layout_of(element_type).map(|l| l.size.bytes());
if let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes());
if self.maximum_allowed_size < element_count * element_size;
then {

View File

@ -43,9 +43,9 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays {
if_chain! {
if let ExprKind::Repeat(_, _) = expr.kind;
if let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind();
if let ConstKind::Value(ConstValue::Scalar(element_count)) = cst.val;
if let ConstKind::Value(ConstValue::Scalar(element_count)) = cst.val();
if let Ok(element_count) = element_count.to_machine_usize(&cx.tcx);
if let Ok(element_size) = cx.layout_of(element_type).map(|l| l.size.bytes());
if let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes());
if self.maximum_allowed_size < element_count * element_size;
then {
span_lint_and_help(

View File

@ -294,7 +294,7 @@ impl LenOutput<'_> {
/// Checks if the given signature matches the expectations for `is_empty`
fn check_is_empty_sig(sig: FnSig<'_>, self_kind: ImplicitSelfKind, len_output: LenOutput<'_>) -> bool {
match &**sig.inputs_and_output {
[arg, res] if len_output.matches_is_empty_output(res) => {
[arg, res] if len_output.matches_is_empty_output(*res) => {
matches!(
(arg.kind(), self_kind),
(ty::Ref(_, _, Mutability::Not), ImplicitSelfKind::ImmRef)

View File

@ -7,7 +7,7 @@ use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_block, walk_expr};
use rustc_hir::{Expr, Pat};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, UintTy};
use rustc_middle::ty::{self, Ty, UintTy};
// To trigger the EXPLICIT_COUNTER_LOOP lint, a variable must be
// incremented exactly once in the loop body, and initialized to zero
@ -36,7 +36,7 @@ pub(super) fn check<'tcx>(
then {
let mut applicability = Applicability::MachineApplicable;
let int_name = match ty.map(ty::TyS::kind) {
let int_name = match ty.map(Ty::kind) {
// usize or inferred
Some(ty::Uint(UintTy::Usize)) | None => {
span_lint_and_sugg(

View File

@ -335,8 +335,8 @@ struct Start<'hir> {
fn get_slice_like_element_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
match ty.kind() {
ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Vec, adt.did) => Some(subs.type_at(0)),
ty::Ref(_, subty, _) => get_slice_like_element_ty(cx, subty),
ty::Slice(ty) | ty::Array(ty, _) => Some(ty),
ty::Ref(_, subty, _) => get_slice_like_element_ty(cx, *subty),
ty::Slice(ty) | ty::Array(ty, _) => Some(*ty),
_ => None,
}
}

View File

@ -12,7 +12,7 @@ use rustc_hir::{Block, Expr, ExprKind, HirId, HirIdSet, Local, Mutability, Node,
use rustc_lint::LateContext;
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, TyS};
use rustc_middle::ty::{self, Ty};
use rustc_span::sym;
use rustc_span::{MultiSpan, Span};
@ -334,8 +334,8 @@ fn detect_iter_and_into_iters<'tcx: 'a, 'a>(
}
}
fn get_captured_ids(cx: &LateContext<'_>, ty: &'_ TyS<'_>) -> HirIdSet {
fn get_captured_ids_recursive(cx: &LateContext<'_>, ty: &'_ TyS<'_>, set: &mut HirIdSet) {
fn get_captured_ids(cx: &LateContext<'_>, ty: Ty<'_>) -> HirIdSet {
fn get_captured_ids_recursive(cx: &LateContext<'_>, ty: Ty<'_>, set: &mut HirIdSet) {
match ty.kind() {
ty::Adt(_, generics) => {
for generic in *generics {

View File

@ -334,7 +334,7 @@ pub(super) fn make_iterator_snippet(cx: &LateContext<'_>, arg: &Expr<'_>, applic
// (&mut x).into_iter() ==> x.iter_mut()
let arg_ty = cx.typeck_results().expr_ty_adjusted(arg);
match &arg_ty.kind() {
ty::Ref(_, inner_ty, mutbl) if has_iter_method(cx, inner_ty).is_some() => {
ty::Ref(_, inner_ty, mutbl) if has_iter_method(cx, *inner_ty).is_some() => {
let method_name = match mutbl {
Mutability::Mut => "iter_mut",
Mutability::Not => "iter",

View File

@ -100,7 +100,7 @@ impl<'tcx> LateLintPass<'tcx> for MapClone {
let obj_ty = cx.typeck_results().expr_ty(obj);
if let ty::Ref(_, ty, mutability) = obj_ty.kind() {
if matches!(mutability, Mutability::Not) {
let copy = is_copy(cx, ty);
let copy = is_copy(cx, *ty);
self.lint_explicit_closure(cx, e.span, args[0].span, copy);
}
} else {

View File

@ -54,8 +54,8 @@ fn type_needs_ordered_drop_inner<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, see
// This type doesn't implement drop, so no side effects here.
// Check if any component type has any.
match ty.kind() {
ty::Tuple(_) => ty.tuple_fields().any(|ty| type_needs_ordered_drop_inner(cx, ty, seen)),
ty::Array(ty, _) => type_needs_ordered_drop_inner(cx, ty, seen),
ty::Tuple(fields) => fields.iter().any(|ty| type_needs_ordered_drop_inner(cx, ty, seen)),
ty::Array(ty, _) => type_needs_ordered_drop_inner(cx, *ty, seen),
ty::Adt(adt, subs) => adt
.all_fields()
.map(|f| f.ty(cx.tcx, subs))

View File

@ -8,7 +8,7 @@ use core::cmp::max;
use rustc_errors::Applicability;
use rustc_hir::{Arm, BindingAnnotation, Block, Expr, ExprKind, Pat, PatKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty, TyS};
use rustc_middle::ty::{self, Ty};
use super::{MATCH_BOOL, SINGLE_MATCH, SINGLE_MATCH_ELSE};
@ -162,10 +162,10 @@ fn check_opt_like<'a>(
return;
}
let in_candidate_enum = |path_info: &(String, &TyS<'_>)| -> bool {
let in_candidate_enum = |path_info: &(String, Ty<'_>)| -> bool {
let (path, ty) = path_info;
for &(ty_path, pat_path) in candidates {
if path == pat_path && match_type(cx, ty, ty_path) {
if path == pat_path && match_type(cx, *ty, ty_path) {
return true;
}
}

View File

@ -30,7 +30,7 @@ pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span,
};
match inner_ty.kind() {
// &T where T: Copy
ty::Ref(_, ty, _) if is_copy(cx, ty) => {},
ty::Ref(_, ty, _) if is_copy(cx, *ty) => {},
_ => return,
};
span_lint_and_sugg(

View File

@ -73,7 +73,7 @@ pub(super) fn check<'tcx>(
match cx.qpath_res(p, fun.hir_id) {
hir::def::Res::Def(hir::def::DefKind::Fn | hir::def::DefKind::AssocFn, def_id) => matches!(
cx.tcx.fn_sig(def_id).output().skip_binder().kind(),
ty::Ref(ty::ReStatic, ..)
ty::Ref(re, ..) if re.is_static(),
),
_ => false,
}
@ -87,7 +87,7 @@ pub(super) fn check<'tcx>(
.map_or(false, |method_id| {
matches!(
cx.tcx.fn_sig(method_id).output().skip_binder().kind(),
ty::Ref(ty::ReStatic, ..)
ty::Ref(re, ..) if re.is_static()
)
})
},

View File

@ -26,7 +26,7 @@ pub(super) fn check<'tcx>(
};
match inner_ty.kind() {
ty::Ref(_, ty, _) if !is_copy(cx, ty) => {},
ty::Ref(_, ty, _) if !is_copy(cx, *ty) => {},
_ => return,
};

View File

@ -8,7 +8,7 @@ use rustc_ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, LangItem};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty, TyS};
use rustc_middle::ty::{self, Ty};
use rustc_span::symbol::sym;
use std::borrow::Cow;
@ -37,8 +37,8 @@ fn parse_repeat_arg(cx: &LateContext<'_>, e: &Expr<'_>) -> Option<RepeatKind> {
} else {
let ty = cx.typeck_results().expr_ty(e);
if is_type_diagnostic_item(cx, ty, sym::String)
|| (is_type_lang_item(cx, ty, LangItem::OwnedBox) && get_ty_param(ty).map_or(false, TyS::is_str))
|| (match_type(cx, ty, &paths::COW) && get_ty_param(ty).map_or(false, TyS::is_str))
|| (is_type_lang_item(cx, ty, LangItem::OwnedBox) && get_ty_param(ty).map_or(false, Ty::is_str))
|| (match_type(cx, ty, &paths::COW) && get_ty_param(ty).map_or(false, Ty::is_str))
{
Some(RepeatKind::String)
} else {

View File

@ -2106,7 +2106,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
let method_sig = cx.tcx.fn_sig(impl_item.def_id);
let method_sig = cx.tcx.erase_late_bound_regions(method_sig);
let first_arg_ty = &method_sig.inputs().iter().next();
let first_arg_ty = method_sig.inputs().iter().next();
// check conventions w.r.t. conversion method names and predicates
if let Some(first_arg_ty) = first_arg_ty;
@ -2119,7 +2119,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
if name == method_config.method_name &&
sig.decl.inputs.len() == method_config.param_count &&
method_config.output_type.matches(&sig.decl.output) &&
method_config.self_kind.matches(cx, self_ty, first_arg_ty) &&
method_config.self_kind.matches(cx, self_ty, *first_arg_ty) &&
fn_header_equals(method_config.fn_header, sig.header) &&
method_config.lifetime_param_cond(impl_item)
{
@ -2151,7 +2151,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
cx,
name,
self_ty,
first_arg_ty,
*first_arg_ty,
first_arg.pat.span,
implements_trait,
false

View File

@ -105,7 +105,7 @@ fn check_addr_of_expr(
if is_copy(cx, receiver_ty) || is_cow_into_owned(cx, method_name, method_def_id);
if let Some(receiver_snippet) = snippet_opt(cx, receiver.span);
then {
let (target_ty, n_target_refs) = peel_mid_ty_refs(target_ty);
let (target_ty, n_target_refs) = peel_mid_ty_refs(*target_ty);
let (receiver_ty, n_receiver_refs) = peel_mid_ty_refs(receiver_ty);
if receiver_ty == target_ty && n_target_refs >= n_receiver_refs {
span_lint_and_sugg(
@ -228,7 +228,7 @@ fn check_other_call_arg<'tcx>(
let fn_sig = cx.tcx.fn_sig(callee_def_id).skip_binder();
if let Some(i) = call_args.iter().position(|arg| arg.hir_id == maybe_arg.hir_id);
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);
if let (trait_predicates, projection_predicates) = get_input_traits_and_projections(cx, callee_def_id, input);
if let Some(sized_def_id) = cx.tcx.lang_items().sized_trait();
if let [trait_predicate] = trait_predicates

View File

@ -19,7 +19,7 @@ pub(super) fn derefs_to_slice<'tcx>(
ty::Adt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()),
ty::Adt(..) => is_type_diagnostic_item(cx, ty, sym::Vec),
ty::Array(_, size) => size.try_eval_usize(cx.tcx, cx.param_env).is_some(),
ty::Ref(_, inner, _) => may_slice(cx, inner),
ty::Ref(_, inner, _) => may_slice(cx, *inner),
_ => false,
}
}
@ -35,7 +35,7 @@ pub(super) fn derefs_to_slice<'tcx>(
ty::Slice(_) => Some(expr),
ty::Adt(def, _) if def.is_box() && may_slice(cx, ty.boxed_ty()) => Some(expr),
ty::Ref(_, inner, _) => {
if may_slice(cx, inner) {
if may_slice(cx, *inner) {
Some(expr)
} else {
None

View File

@ -2,7 +2,7 @@ use crate::methods::SelfKind;
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::is_copy;
use rustc_lint::LateContext;
use rustc_middle::ty::TyS;
use rustc_middle::ty::Ty;
use rustc_span::source_map::Span;
use std::fmt;
@ -41,7 +41,7 @@ impl Convention {
fn check<'tcx>(
&self,
cx: &LateContext<'tcx>,
self_ty: &'tcx TyS<'tcx>,
self_ty: Ty<'tcx>,
other: &str,
implements_trait: bool,
is_trait_item: bool,
@ -84,8 +84,8 @@ impl fmt::Display for Convention {
pub(super) fn check<'tcx>(
cx: &LateContext<'tcx>,
item_name: &str,
self_ty: &'tcx TyS<'tcx>,
first_arg_ty: &'tcx TyS<'tcx>,
self_ty: Ty<'tcx>,
first_arg_ty: Ty<'tcx>,
first_arg_span: Span,
implements_trait: bool,
is_trait_item: bool,

View File

@ -9,7 +9,7 @@ use super::ZST_OFFSET;
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {
if_chain! {
if let ty::RawPtr(ty::TypeAndMut { ty, .. }) = cx.typeck_results().expr_ty(recv).kind();
if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty));
if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(*ty));
if layout.is_zst();
then {
span_lint(cx, ZST_OFFSET, expr.span, "offset calculation on zero-sized value");

View File

@ -4,7 +4,7 @@ use clippy_utils::sext;
use if_chain::if_chain;
use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_middle::ty::{self, Ty};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use std::fmt::Display;
@ -77,7 +77,7 @@ fn floating_point_operand_info<T: Display + PartialOrd + From<f32>>(f: &T) -> Op
}
}
fn might_have_negative_value(t: &ty::TyS<'_>) -> bool {
fn might_have_negative_value(t: Ty<'_>) -> bool {
t.is_signed() || t.is_floating_point()
}

View File

@ -113,7 +113,7 @@ fn check_sig<'tcx>(cx: &LateContext<'tcx>, item_hir_id: hir::HirId, decl: &hir::
let fn_def_id = cx.tcx.hir().local_def_id(item_hir_id);
let fn_sig = cx.tcx.fn_sig(fn_def_id);
for (hir_ty, ty) in iter::zip(decl.inputs, fn_sig.inputs().skip_binder()) {
check_ty(cx, hir_ty.span, ty);
check_ty(cx, hir_ty.span, *ty);
}
check_ty(cx, decl.output.span(), cx.tcx.erase_late_bound_regions(fn_sig.output()));
}
@ -142,7 +142,7 @@ fn is_interior_mutable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Sp
size.try_eval_usize(cx.tcx, cx.param_env).map_or(true, |u| u != 0)
&& is_interior_mutable_type(cx, inner_ty, span)
},
Tuple(..) => ty.tuple_fields().any(|ty| is_interior_mutable_type(cx, ty, span)),
Tuple(fields) => fields.iter().any(|ty| is_interior_mutable_type(cx, ty, span)),
Adt(def, substs) => {
// 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`

View File

@ -53,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for MutMutexLock {
if path.ident.name == sym!(lock);
let ty = cx.typeck_results().expr_ty(self_arg);
if let ty::Ref(_, inner_ty, Mutability::Mut) = ty.kind();
if is_type_diagnostic_item(cx, inner_ty, sym::Mutex);
if is_type_diagnostic_item(cx, *inner_ty, sym::Mutex);
then {
span_lint_and_sugg(
cx,

View File

@ -136,14 +136,14 @@ fn is_value_unfrozen_raw<'tcx>(
result: Result<ConstValue<'tcx>, ErrorHandled>,
ty: Ty<'tcx>,
) -> bool {
fn inner<'tcx>(cx: &LateContext<'tcx>, val: &'tcx Const<'tcx>) -> bool {
match val.ty.kind() {
fn inner<'tcx>(cx: &LateContext<'tcx>, val: Const<'tcx>) -> bool {
match val.ty().kind() {
// the fact that we have to dig into every structs to search enums
// leads us to the point checking `UnsafeCell` directly is the only option.
ty::Adt(ty_def, ..) if Some(ty_def.did) == cx.tcx.lang_items().unsafe_cell_type() => true,
ty::Array(..) | ty::Adt(..) | ty::Tuple(..) => {
let val = cx.tcx.destructure_const(cx.param_env.and(val));
val.fields.iter().any(|field| inner(cx, field))
val.fields.iter().any(|field| inner(cx, *field))
},
_ => false,
}

View File

@ -202,10 +202,10 @@ fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t
// The type is known to be `!Send` and `!Copy`
match ty.kind() {
ty::Tuple(_) => ty
.tuple_fields()
ty::Tuple(fields) => fields
.iter()
.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) => {
if contains_pointer_like(cx, ty) {
// descends only if ADT contains any raw pointers

View File

@ -167,8 +167,8 @@ impl<'tcx> PassByRefOrValue {
if_chain! {
if !output_lts.contains(input_lt);
if is_copy(cx, ty);
if let Some(size) = cx.layout_of(ty).ok().map(|l| l.size.bytes());
if is_copy(cx, *ty);
if let Some(size) = cx.layout_of(*ty).ok().map(|l| l.size.bytes());
if size <= self.ref_min_size;
if let hir::TyKind::Rptr(_, MutTy { ty: decl_ty, .. }) = input.kind;
then {

View File

@ -116,7 +116,7 @@ fn get_pointee_ty_and_count_expr<'tcx>(
if let ty::RawPtr(TypeAndMut { ty: pointee_ty, .. }) =
cx.typeck_results().expr_ty(ptr_self).kind();
then {
return Some((pointee_ty, count));
return Some((*pointee_ty, count));
}
};
None

View File

@ -98,8 +98,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate;
if !bound_predicate.span.from_expansion();
if let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind;
if let Some(PathSegment { res: Some(Res::SelfTy(Some(def_id), _)), .. }) = segments.first();
if let Some(PathSegment {
res: Some(Res::SelfTy{ trait_: Some(def_id), alias_to: _ }), ..
}) = segments.first();
if let Some(
Node::Item(
Item {

View File

@ -38,7 +38,7 @@ pub(super) fn check<'tcx>(
let arg = if from_ptr_ty.ty == *to_ref_ty {
arg
} else {
arg.as_ty(&format!("{} {}", cast, get_type_snippet(cx, qpath, to_ref_ty)))
arg.as_ty(&format!("{} {}", cast, get_type_snippet(cx, qpath, *to_ref_ty)))
};
diag.span_suggestion(

View File

@ -56,10 +56,10 @@ pub(super) fn check<'tcx>(
"transmute from a reference to a reference",
|diag| if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
let ty_from_and_mut = ty::TypeAndMut {
ty: ty_from,
ty: *ty_from,
mutbl: *from_mutbl
};
let ty_to_and_mut = ty::TypeAndMut { ty: ty_to, mutbl: *to_mutbl };
let ty_to_and_mut = ty::TypeAndMut { ty: *ty_to, mutbl: *to_mutbl };
let sugg_paren = arg
.as_ty(cx.tcx.mk_ptr(ty_from_and_mut))
.as_ty(cx.tcx.mk_ptr(ty_to_and_mut));

View File

@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::ty::is_c_void;
use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_middle::ty::subst::{GenericArg, Subst};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{self, Ty, TypeAndMut};
use rustc_span::Span;
@ -135,19 +135,21 @@ pub(super) fn check<'tcx>(
from_ty_orig, to_ty_orig
),
|diag| {
if let (Some(from_def), Some(to_def)) = (from_ty.ty_adt_def(), to_ty.ty_adt_def())
&& from_def == to_def
{
diag.note(&format!(
"two instances of the same generic type (`{}`) may have different layouts",
cx.tcx.item_name(from_def.did)
));
} else {
if from_ty_orig.peel_refs() != from_ty {
diag.note(&format!("the contained type `{}` has an undefined layout", from_ty));
}
if to_ty_orig.peel_refs() != to_ty {
diag.note(&format!("the contained type `{}` has an undefined layout", to_ty));
if_chain! {
if let (Some(from_def), Some(to_def)) = (from_ty.ty_adt_def(), to_ty.ty_adt_def());
if from_def == to_def;
then {
diag.note(&format!(
"two instances of the same generic type (`{}`) may have different layouts",
cx.tcx.item_name(from_def.did)
));
} else {
if from_ty_orig.peel_refs() != from_ty {
diag.note(&format!("the contained type `{}` has an undefined layout", from_ty));
}
if to_ty_orig.peel_refs() != to_ty {
diag.note(&format!("the contained type `{}` has an undefined layout", to_ty));
}
}
}
},
@ -223,27 +225,27 @@ fn reduce_refs<'tcx>(
loop {
return match (from_ty.kind(), to_ty.kind()) {
(
ty::Ref(_, from_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: from_sub_ty, .. }),
ty::Ref(_, to_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: to_sub_ty, .. }),
&(ty::Ref(_, from_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: from_sub_ty, .. })),
&(ty::Ref(_, to_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: to_sub_ty, .. })),
) => {
from_ty = from_sub_ty;
to_ty = to_sub_ty;
continue;
},
(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. }), _)
(&(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })), _)
if !unsized_ty.is_sized(cx.tcx.at(span), cx.param_env) =>
{
ReducedTys::FromFatPtr { unsized_ty, to_ty }
},
(_, ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. }))
(_, &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })))
if !unsized_ty.is_sized(cx.tcx.at(span), cx.param_env) =>
{
ReducedTys::ToFatPtr { unsized_ty, from_ty }
},
(ty::Ref(_, from_ty, _) | ty::RawPtr(TypeAndMut { ty: from_ty, .. }), _) => {
(&(ty::Ref(_, from_ty, _) | ty::RawPtr(TypeAndMut { ty: from_ty, .. })), _) => {
ReducedTys::FromPtr { from_ty, to_ty }
},
(_, ty::Ref(_, to_ty, _) | ty::RawPtr(TypeAndMut { ty: to_ty, .. })) => {
(_, &(ty::Ref(_, to_ty, _) | ty::RawPtr(TypeAndMut { ty: to_ty, .. }))) => {
ReducedTys::ToPtr { from_ty, to_ty }
},
_ => ReducedTys::Other { from_ty, to_ty },
@ -280,11 +282,10 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
},
ty::Tuple(args) if args.is_empty() => ReducedTy::TypeErasure,
ty::Tuple(args) => {
let mut iter = args.iter().map(GenericArg::expect_ty);
let Some(sized_ty) = iter.find(|ty| !is_zero_sized_ty(cx, ty)) else {
let Some(sized_ty) = args.iter().find(|&ty| !is_zero_sized_ty(cx, ty)) else {
return ReducedTy::OrderedFields(ty);
};
if iter.all(|ty| is_zero_sized_ty(cx, ty)) {
if args.iter().all(|ty| is_zero_sized_ty(cx, ty)) {
ty = sized_ty;
continue;
}
@ -296,7 +297,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
.fields
.iter()
.map(|f| cx.tcx.type_of(f.did).subst(cx.tcx, substs));
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;
};
if iter.all(|ty| is_zero_sized_ty(cx, ty)) {
@ -321,11 +322,13 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
}
fn is_zero_sized_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
if let Ok(ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, ty)
&& let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty))
{
layout.layout.size.bytes() == 0
} else {
false
if_chain! {
if let Ok(ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, ty);
if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty));
then {
layout.layout.size.bytes() == 0
} else {
false
}
}
}

View File

@ -34,7 +34,7 @@ pub(super) fn check<'tcx>(
|diag| {
if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
let rty_and_mut = ty::TypeAndMut {
ty: rty,
ty: *rty,
mutbl: *rty_mutbl,
};

View File

@ -84,7 +84,8 @@ fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Ve
let partial_ord_preds =
get_trait_predicates_for_trait_id(cx, generics, cx.tcx.lang_items().partial_ord_trait());
// Trying to call erase_late_bound_regions on fn_sig.inputs() gives the following error
// The trait `rustc::ty::TypeFoldable<'_>` is not implemented for `&[&rustc::ty::TyS<'_>]`
// The trait `rustc::ty::TypeFoldable<'_>` is not implemented for
// `&[rustc_middle::ty::Ty<'_>]`
let inputs_output = cx.tcx.erase_late_bound_regions(fn_sig.inputs_and_output());
inputs_output
.iter()

View File

@ -204,7 +204,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
ref types_to_skip,
}) = self.stack.last();
if let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind;
if !matches!(path.res, Res::SelfTy(..) | Res::Def(DefKind::TyParam, _));
if !matches!(path.res, Res::SelfTy { .. } | Res::Def(DefKind::TyParam, _));
if !types_to_skip.contains(&hir_ty.hir_id);
let ty = if in_body > 0 {
cx.typeck_results().node_type(hir_ty.hir_id)
@ -231,7 +231,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
}
match expr.kind {
ExprKind::Struct(QPath::Resolved(_, path), ..) => match path.res {
Res::SelfTy(..) => (),
Res::SelfTy { .. } => (),
Res::Def(DefKind::Variant, _) => lint_path_to_variant(cx, path),
_ => span_lint(cx, path.span),
},

View File

@ -1305,7 +1305,7 @@ fn if_chain_local_span(cx: &LateContext<'_>, local: &Local<'_>, if_chain_span: S
}
span.adjust(if_chain_span.ctxt().outer_expn());
let sm = cx.sess().source_map();
let span = sm.span_extend_to_prev_str(span, "let", false);
let span = sm.span_extend_to_prev_str(span, "let", false, true).unwrap_or(span);
let span = sm.span_extend_to_next_char(span, ';', false);
Span::new(
span.lo() - BytePos(3),

View File

@ -453,7 +453,7 @@ impl SimpleFormatArgs {
}
}
},
ArgumentNamed(n) => {
ArgumentNamed(n, _) => {
if let Some(x) = self.named.iter_mut().find(|x| x.0 == n) {
match x.1.as_slice() {
// A non-empty format string has been seen already.

View File

@ -1,6 +1,6 @@
[package]
name = "clippy_utils"
version = "0.1.60"
version = "0.1.61"
edition = "2021"
publish = false

View File

@ -567,11 +567,11 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
}
}
pub fn miri_to_const(result: &ty::Const<'_>) -> Option<Constant> {
pub fn miri_to_const(result: ty::Const<'_>) -> Option<Constant> {
use rustc_middle::mir::interpret::ConstValue;
match result.val {
match result.val() {
ty::ConstKind::Value(ConstValue::Scalar(Scalar::Int(int))) => {
match result.ty.kind() {
match result.ty().kind() {
ty::Bool => Some(Constant::Bool(int == ScalarInt::TRUE)),
ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.assert_bits(int.size()))),
ty::Float(FloatTy::F32) => Some(Constant::F32(f32::from_bits(
@ -590,7 +590,7 @@ pub fn miri_to_const(result: &ty::Const<'_>) -> Option<Constant> {
_ => None,
}
},
ty::ConstKind::Value(ConstValue::Slice { data, start, end }) => match result.ty.kind() {
ty::ConstKind::Value(ConstValue::Slice { data, start, end }) => match result.ty().kind() {
ty::Ref(_, tam, _) => match tam.kind() {
ty::Str => String::from_utf8(
data.inspect_with_uninit_and_ptr_outside_interpreter(start..end)
@ -602,9 +602,9 @@ pub fn miri_to_const(result: &ty::Const<'_>) -> Option<Constant> {
},
_ => None,
},
ty::ConstKind::Value(ConstValue::ByRef { alloc, offset: _ }) => match result.ty.kind() {
ty::ConstKind::Value(ConstValue::ByRef { alloc, offset: _ }) => match result.ty().kind() {
ty::Array(sub_type, len) => match sub_type.kind() {
ty::Float(FloatTy::F32) => match miri_to_const(len) {
ty::Float(FloatTy::F32) => match miri_to_const(*len) {
Some(Constant::Int(len)) => alloc
.inspect_with_uninit_and_ptr_outside_interpreter(0..(4 * len as usize))
.to_owned()
@ -618,7 +618,7 @@ pub fn miri_to_const(result: &ty::Const<'_>) -> Option<Constant> {
.map(Constant::Vec),
_ => None,
},
ty::Float(FloatTy::F64) => match miri_to_const(len) {
ty::Float(FloatTy::F64) => match miri_to_const(*len) {
Some(Constant::Int(len)) => alloc
.inspect_with_uninit_and_ptr_outside_interpreter(0..(8 * len as usize))
.to_owned()

View File

@ -1461,7 +1461,7 @@ pub fn is_self(slf: &Param<'_>) -> bool {
pub fn is_self_ty(slf: &hir::Ty<'_>) -> bool {
if let TyKind::Path(QPath::Resolved(None, path)) = slf.kind {
if let Res::SelfTy(..) = path.res {
if let Res::SelfTy { .. } = path.res {
return true;
}
}
@ -1912,10 +1912,10 @@ pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<S
let expr_type = cx.typeck_results().expr_ty_adjusted(expr);
let expr_kind = expr_type.kind();
let is_primitive = match expr_kind {
rustc_ty::Slice(element_type) => is_recursively_primitive_type(element_type),
rustc_ty::Slice(element_type) => is_recursively_primitive_type(*element_type),
rustc_ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), &rustc_ty::Slice(_)) => {
if let rustc_ty::Slice(element_type) = inner_ty.kind() {
is_recursively_primitive_type(element_type)
is_recursively_primitive_type(*element_type)
} else {
unreachable!()
}

View File

@ -32,7 +32,6 @@ pub fn is_min_const_fn<'a, 'tcx>(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv:
| ty::PredicateKind::Projection(_)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate),
ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {:#?}", predicate),
@ -150,7 +149,7 @@ fn check_rvalue<'tcx>(
Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
use rustc_middle::ty::cast::CastTy;
let cast_in = CastTy::from_ty(operand.ty(body, tcx)).expect("bad input type for cast");
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
let cast_out = CastTy::from_ty(*cast_ty).expect("bad output type for cast");
match (cast_in, cast_out) {
(CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => {
Err((span, "casting pointers to ints is unstable in const fn".into()))

View File

@ -105,7 +105,7 @@ pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option<
];
let ty_to_check = match probably_ref_ty.kind() {
ty::Ref(_, ty_to_check, _) => ty_to_check,
ty::Ref(_, ty_to_check, _) => *ty_to_check,
_ => probably_ref_ty,
};
@ -171,7 +171,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
is_must_use_ty(cx, *ty)
},
ty::Tuple(substs) => substs.types().any(|ty| is_must_use_ty(cx, ty)),
ty::Tuple(substs) => substs.iter().any(|ty| is_must_use_ty(cx, ty)),
ty::Opaque(ref def_id, _) => {
for (predicate, _) in cx.tcx.explicit_item_bounds(*def_id) {
if let ty::PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder() {
@ -211,7 +211,7 @@ fn is_normalizable_helper<'tcx>(
ty: Ty<'tcx>,
cache: &mut FxHashMap<Ty<'tcx>, bool>,
) -> bool {
if let Some(&cached_result) = cache.get(ty) {
if let Some(&cached_result) = cache.get(&ty) {
return cached_result;
}
// prevent recursive loops, false-negative is better than endless loop leading to stack overflow
@ -251,11 +251,11 @@ pub fn is_non_aggregate_primitive_type(ty: Ty<'_>) -> bool {
/// Returns `true` if the given type is a primitive (a `bool` or `char`, any integer or
/// floating-point number type, a `str`, or an array, slice, or tuple of those types).
pub fn is_recursively_primitive_type(ty: Ty<'_>) -> bool {
match ty.kind() {
match *ty.kind() {
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => true,
ty::Ref(_, inner, _) if *inner.kind() == ty::Str => true,
ty::Array(inner_type, _) | ty::Slice(inner_type) => is_recursively_primitive_type(inner_type),
ty::Tuple(inner_types) => inner_types.types().all(is_recursively_primitive_type),
ty::Tuple(inner_types) => inner_types.iter().all(is_recursively_primitive_type),
_ => false,
}
}
@ -320,7 +320,7 @@ pub fn match_type(cx: &LateContext<'_>, ty: Ty<'_>, path: &[&str]) -> bool {
pub fn peel_mid_ty_refs(ty: Ty<'_>) -> (Ty<'_>, usize) {
fn peel(ty: Ty<'_>, count: usize) -> (Ty<'_>, usize) {
if let ty::Ref(_, ty, _) = ty.kind() {
peel(ty, count + 1)
peel(*ty, count + 1)
} else {
(ty, count)
}
@ -333,8 +333,8 @@ pub fn peel_mid_ty_refs(ty: Ty<'_>) -> (Ty<'_>, usize) {
pub fn peel_mid_ty_refs_is_mutable(ty: Ty<'_>) -> (Ty<'_>, usize, Mutability) {
fn f(ty: Ty<'_>, count: usize, mutability: Mutability) -> (Ty<'_>, usize, Mutability) {
match ty.kind() {
ty::Ref(_, ty, Mutability::Mut) => f(ty, count + 1, mutability),
ty::Ref(_, ty, Mutability::Not) => f(ty, count + 1, Mutability::Not),
ty::Ref(_, ty, Mutability::Mut) => f(*ty, count + 1, mutability),
ty::Ref(_, ty, Mutability::Not) => f(*ty, count + 1, Mutability::Not),
_ => (ty, count, mutability),
}
}
@ -362,7 +362,7 @@ pub fn walk_ptrs_hir_ty<'tcx>(ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {
pub fn walk_ptrs_ty_depth(ty: Ty<'_>) -> (Ty<'_>, usize) {
fn inner(ty: Ty<'_>, depth: usize) -> (Ty<'_>, usize) {
match ty.kind() {
ty::Ref(_, ty, _) => inner(ty, depth + 1),
ty::Ref(_, ty, _) => inner(*ty, depth + 1),
_ => (ty, depth),
}
}
@ -395,9 +395,9 @@ pub fn same_type_and_consts<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
/// Checks if a given type looks safe to be uninitialized.
pub fn is_uninit_value_valid_for_ty(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
match ty.kind() {
match *ty.kind() {
ty::Array(component, _) => is_uninit_value_valid_for_ty(cx, component),
ty::Tuple(types) => types.types().all(|ty| is_uninit_value_valid_for_ty(cx, ty)),
ty::Tuple(types) => types.iter().all(|ty| is_uninit_value_valid_for_ty(cx, ty)),
ty::Adt(adt, _) => cx.tcx.lang_items().maybe_uninit() == Some(adt.did),
_ => false,
}
@ -428,8 +428,8 @@ impl<'tcx> ExprFnSig<'tcx> {
pub fn input(self, i: usize) -> Binder<'tcx, Ty<'tcx>> {
match self {
Self::Sig(sig) => sig.input(i),
Self::Closure(sig) => sig.input(0).map_bound(|ty| ty.tuple_element_ty(i).unwrap()),
Self::Trait(inputs, _) => inputs.map_bound(|ty| ty.tuple_element_ty(i).unwrap()),
Self::Closure(sig) => sig.input(0).map_bound(|ty| ty.tuple_fields()[i]),
Self::Trait(inputs, _) => inputs.map_bound(|ty| ty.tuple_fields()[i]),
}
}

View File

@ -26,7 +26,7 @@ Sometimes you may want to retrieve the type `Ty` of an expression `Expr`, for ex
- does it implement a trait?
This operation is performed using the [`expr_ty()`][expr_ty] method from the [`TypeckResults`][TypeckResults] struct,
that gives you access to the underlying structure [`TyS`][TyS].
that gives you access to the underlying structure [`Ty`][Ty].
Example of use:
```rust
@ -259,7 +259,7 @@ expression with a different context from `a`.
assert_eq!(x_is_some_span.ctxt(), x_unwrap_span.ctxt());
```
[TyS]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html
[Ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
[TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html
[TypeckResults]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html
[expr_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.expr_ty

View File

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