r? @ghost

changelog: none
This commit is contained in:
Philipp Krones 2024-11-28 18:03:28 +00:00 committed by GitHub
commit ff4a26d442
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
63 changed files with 265 additions and 237 deletions

View file

@ -1,7 +1,7 @@
[package]
name = "clippy"
# begin autogenerated version
version = "0.1.84"
version = "0.1.85"
# end autogenerated version
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
@ -29,7 +29,7 @@ rustc_tools_util = "0.4.0"
tempfile = { version = "3.3", optional = true }
termize = "0.1"
color-print = "0.3.4"
anstream = "0.6.0"
anstream = "0.6.18"
[dev-dependencies]
cargo_metadata = "0.18.1"

View file

@ -1,7 +1,7 @@
[package]
name = "clippy_config"
# begin autogenerated version
version = "0.1.84"
version = "0.1.85"
# end autogenerated version
edition = "2021"
publish = false

View file

@ -1,7 +1,7 @@
[package]
name = "clippy_lints"
# begin autogenerated version
version = "0.1.84"
version = "0.1.85"
# end autogenerated version
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"

View file

@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones {
},
_ => return,
}
&& let Ok(Some(resolved_fn)) = Instance::try_resolve(cx.tcx, cx.param_env, fn_id, fn_gen_args)
&& let Ok(Some(resolved_fn)) = Instance::try_resolve(cx.tcx, cx.typing_env(), fn_id, fn_gen_args)
// TODO: This check currently bails if the local variable has no initializer.
// That is overly conservative - the lint should fire even if there was no initializer,
// but the variable has been initialized before `lhs` was evaluated.

View file

@ -62,7 +62,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -
})
.is_some_and(|assoc_item| {
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.typing_env(), proj);
nty.is_bool()
})

View file

@ -39,7 +39,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) {
(Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut))
// The `U` in `pointer::cast` have to be `Sized`
// as explained here: https://github.com/rust-lang/rust/issues/60602.
&& to_pointee_ty.is_sized(cx.tcx, cx.param_env)
&& to_pointee_ty.is_sized(cx.tcx, cx.typing_env())
{
let mut app = Applicability::MachineApplicable;
let turbofish = match &cast_to_hir_ty.kind {

View file

@ -10,6 +10,7 @@ use core::mem;
use rustc_ast::util::parser::{PREC_PREFIX, PREC_UNAMBIGUOUS};
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::Applicability;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{Visitor, walk_ty};
use rustc_hir::{
self as hir, BindingMode, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node, Pat,
@ -17,7 +18,7 @@ use rustc_hir::{
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitableExt, TypeckResults};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeckResults};
use rustc_session::impl_lint_pass;
use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol};
@ -753,10 +754,10 @@ impl TyCoercionStability {
fn for_defined_ty<'tcx>(cx: &LateContext<'tcx>, ty: DefinedTy<'tcx>, for_return: bool) -> Self {
match ty {
DefinedTy::Hir(ty) => Self::for_hir_ty(ty),
DefinedTy::Mir(ty) => Self::for_mir_ty(
DefinedTy::Mir { def_site_def_id, ty } => Self::for_mir_ty(
cx.tcx,
ty.param_env,
cx.tcx.instantiate_bound_regions_with_erased(ty.value),
def_site_def_id,
cx.tcx.instantiate_bound_regions_with_erased(ty),
for_return,
),
}
@ -823,12 +824,15 @@ impl TyCoercionStability {
}
}
fn for_mir_ty<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>, for_return: bool) -> Self {
fn for_mir_ty<'tcx>(tcx: TyCtxt<'tcx>, def_site_def_id: Option<DefId>, ty: Ty<'tcx>, for_return: bool) -> Self {
let ty::Ref(_, mut ty, _) = *ty.kind() else {
return Self::None;
};
ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty);
if let Some(def_id) = def_site_def_id {
let typing_env = ty::TypingEnv::non_body_analysis(tcx, def_id);
ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);
}
loop {
break match *ty.kind() {
ty::Ref(_, ref_ty, _) => {
@ -959,7 +963,7 @@ fn report<'tcx>(
// expr_str (the suggestion) is never shown if is_final_ufcs is true, since it's
// `expr.kind == ExprKind::Call`. Therefore, this is, afaik, always unnecessary.
/*
expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence().order() < PREC_PREFIX {
expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence() < PREC_PREFIX {
Cow::Owned(format!("({expr_str})"))
} else {
expr_str
@ -999,7 +1003,7 @@ fn report<'tcx>(
Node::Expr(e) => match e.kind {
ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => (0, false),
ExprKind::Call(..) => (PREC_UNAMBIGUOUS, matches!(expr.kind, ExprKind::Field(..))),
_ => (e.precedence().order(), false),
_ => (e.precedence(), false),
},
_ => (0, false),
};
@ -1012,7 +1016,7 @@ fn report<'tcx>(
);
let sugg = if !snip_is_macro
&& (calls_field || expr.precedence().order() < precedence)
&& (calls_field || expr.precedence() < precedence)
&& !has_enclosing_paren(&snip)
&& !is_in_tuple
{
@ -1027,7 +1031,7 @@ fn report<'tcx>(
State::ExplicitDeref { mutability } => {
if is_block_like(expr)
&& let ty::Ref(_, ty, _) = data.adjusted_ty.kind()
&& ty.is_sized(cx.tcx, cx.param_env)
&& ty.is_sized(cx.tcx, cx.typing_env())
{
// Rustc bug: auto deref doesn't work on block expression when targeting sized types.
return;
@ -1066,12 +1070,11 @@ fn report<'tcx>(
let mut app = Applicability::MachineApplicable;
let (snip, snip_is_macro) =
snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app);
let sugg =
if !snip_is_macro && expr.precedence().order() < precedence && !has_enclosing_paren(&snip) {
format!("{prefix}({snip})")
} else {
format!("{prefix}{snip}")
};
let sugg = if !snip_is_macro && expr.precedence() < precedence && !has_enclosing_paren(&snip) {
format!("{prefix}({snip})")
} else {
format!("{prefix}{snip}")
};
diag.span_suggestion(data.first_expr.span, "try", sugg, app);
},
);
@ -1154,7 +1157,7 @@ impl<'tcx> Dereferencing<'tcx> {
},
Some(parent) if !parent.span.from_expansion() => {
// Double reference might be needed at this point.
if parent.precedence().order() == PREC_UNAMBIGUOUS {
if parent.precedence() == PREC_UNAMBIGUOUS {
// Parentheses would be needed here, don't lint.
*outer_pat = None;
} else {

View file

@ -11,7 +11,6 @@ use rustc_hir::{
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
use rustc_middle::traits::Reveal;
use rustc_middle::ty::{
self, ClauseKind, GenericArgKind, GenericParamDefKind, ParamEnv, TraitPredicate, Ty, TyCtxt, Upcast,
};
@ -454,13 +453,13 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
&& cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)
&& !has_non_exhaustive_attr(cx.tcx, *adt)
&& !ty_implements_eq_trait(cx.tcx, ty, eq_trait_def_id)
&& let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
&& let typing_env = typing_env_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
&& let Some(local_def_id) = adt.did().as_local()
// If all of our fields implement `Eq`, we can implement `Eq` too
&& adt
.all_fields()
.map(|f| f.ty(cx.tcx, args))
.all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[]))
.all(|ty| implements_trait_with_env(cx.tcx, typing_env, ty, eq_trait_def_id, None, &[]))
{
span_lint_hir_and_then(
cx,
@ -485,7 +484,7 @@ fn ty_implements_eq_trait<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, eq_trait_id: De
}
/// Creates the `ParamEnv` used for the give type's derived `Eq` impl.
fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> ParamEnv<'_> {
fn typing_env_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> ty::TypingEnv<'_> {
// Initial map from generic index to param def.
// Vec<(param_def, needs_eq)>
let mut params = tcx
@ -506,16 +505,17 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) ->
}
}
ParamEnv::new(
tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain(
params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {
ClauseKind::Trait(TraitPredicate {
trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]),
polarity: ty::PredicatePolarity::Positive,
})
.upcast(tcx)
}),
)),
Reveal::UserFacing,
)
let param_env = ParamEnv::new(tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain(
params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {
ClauseKind::Trait(TraitPredicate {
trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]),
polarity: ty::PredicatePolarity::Positive,
})
.upcast(tcx)
}),
)));
ty::TypingEnv {
typing_mode: ty::TypingMode::non_body_analysis(),
param_env,
}
}

View file

@ -99,7 +99,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef {
sym::mem_forget if is_copy => return,
sym::mem_drop if is_type_lang_item(cx, arg_ty, LangItem::ManuallyDrop) => return,
sym::mem_drop
if !(arg_ty.needs_drop(cx.tcx, cx.param_env)
if !(arg_ty.needs_drop(cx.tcx, cx.typing_env())
|| is_must_use_func_call(cx, arg)
|| is_must_use_ty(cx, arg_ty)
|| drop_is_single_call_in_arm) =>
@ -107,7 +107,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef {
(DROP_NON_DROP, DROP_NON_DROP_SUMMARY.into(), Some(arg.span))
},
sym::mem_forget => {
if arg_ty.needs_drop(cx.tcx, cx.param_env) {
if arg_ty.needs_drop(cx.tcx, cx.typing_env()) {
(
MEM_FORGET,
Cow::Owned(format!(

View file

@ -6,7 +6,7 @@ use rustc_errors::Applicability;
use rustc_hir::intravisit::{Visitor, walk_impl_item, walk_item, walk_param_bound, walk_ty};
use rustc_hir::{
BodyId, ExprKind, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, ImplItemKind, Item, ItemKind,
PredicateOrigin, Ty, WherePredicate,
PredicateOrigin, Ty, WherePredicate, WherePredicateKind,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::hir::nested_filter;
@ -205,12 +205,13 @@ impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> {
}
fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate<'tcx>) {
if let WherePredicate::BoundPredicate(predicate) = predicate {
let span = predicate.span;
if let WherePredicateKind::BoundPredicate(predicate) = predicate.kind {
// Collect spans for any bounds on type parameters.
if let Some((def_id, _)) = predicate.bounded_ty.peel_refs().as_generic_param() {
match predicate.origin {
PredicateOrigin::GenericParam => {
self.inline_bounds.insert(def_id, predicate.span);
self.inline_bounds.insert(def_id, span);
},
PredicateOrigin::WhereClause => {
self.where_bounds.insert(def_id);

View file

@ -198,7 +198,7 @@ fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, tys: &mut DefIdSet)
// primitive types are never mutable
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false,
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.typing_env())
|| matches!(cx.tcx.get_diagnostic_name(adt.did()), Some(sym::Rc | sym::Arc))
&& args.types().any(|ty| is_mutable_ty(cx, ty, tys))
},

View file

@ -4,7 +4,7 @@ use rustc_errors::{Applicability, SuggestionStyle};
use rustc_hir::def_id::DefId;
use rustc_hir::{
AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifiers, TyKind,
WherePredicate,
WherePredicateKind,
};
use rustc_hir_analysis::lower_ty;
use rustc_lint::{LateContext, LateLintPass};
@ -324,7 +324,7 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) {
impl<'tcx> LateLintPass<'tcx> for ImpliedBoundsInImpls {
fn check_generics(&mut self, cx: &LateContext<'tcx>, generics: &rustc_hir::Generics<'tcx>) {
for predicate in generics.predicates {
if let WherePredicate::BoundPredicate(predicate) = predicate
if let WherePredicateKind::BoundPredicate(predicate) = predicate.kind
// In theory, the origin doesn't really matter,
// we *could* also lint on explicit where clauses written out by the user,
// not just impl trait desugared ones, but that contradicts with the lint name...

View file

@ -70,7 +70,7 @@ fn check_sig(cx: &LateContext<'_>, name: Symbol, sig: &FnSig<'_>, fn_id: LocalDe
.instantiate_bound_regions_with_erased(cx.tcx.fn_sig(fn_id).instantiate_identity().output());
let ret_ty = cx
.tcx
.try_normalize_erasing_regions(cx.param_env, ret_ty)
.try_normalize_erasing_regions(cx.typing_env(), ret_ty)
.unwrap_or(ret_ty);
if cx
.tcx

View file

@ -215,7 +215,7 @@ impl {self_ty_without_ref} {{
&& implements_trait(cx, ret_ty, iterator_did, &[])
&& let Some(iter_ty) = make_normalized_projection(
cx.tcx,
cx.param_env,
cx.typing_env(),
iterator_did,
sym::Item,
[ret_ty],

View file

@ -3,8 +3,8 @@ use clippy_utils::diagnostics::span_lint_and_then;
use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, ParamEnv};
use rustc_session::impl_lint_pass;
use rustc_span::{BytePos, Pos, Span};
@ -57,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
&& let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
&& let ty::Array(element_type, cst) = ty.kind()
&& let Some((ty::ValTree::Leaf(element_count), _)) = cx.tcx
.try_normalize_erasing_regions(ParamEnv::empty(), *cst).unwrap_or(*cst).try_to_valtree()
.try_normalize_erasing_regions(cx.typing_env(), *cst).unwrap_or(*cst).try_to_valtree()
&& let element_count = element_count.to_target_usize(cx.tcx)
&& let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
&& u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size)

View file

@ -63,7 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeFuture {
&& let ty = cx.typeck_results().expr_ty(arg)
&& let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait()
&& implements_trait(cx, ty, future_trait_def_id, &[])
&& let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty))
&& let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(ty))
&& let size = layout.layout.size()
&& size >= Size::from_bytes(self.future_size_threshold)
{

View file

@ -150,11 +150,11 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackFrames {
}
let mir = cx.tcx.optimized_mir(def_id);
let param_env = cx.tcx.param_env(def_id);
let typing_env = mir.typing_env(cx.tcx);
let sizes_of_locals = || {
mir.local_decls.iter().filter_map(|local| {
let layout = cx.tcx.layout_of(param_env.and(local.ty)).ok()?;
let layout = cx.tcx.layout_of(typing_env.as_query_input(local.ty)).ok()?;
Some((local, layout.size.bytes()))
})
};

View file

@ -80,7 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for LetIfSeq {
let has_interior_mutability = !cx
.typeck_results()
.node_type(canonical_id)
.is_freeze(cx.tcx, cx.param_env);
.is_freeze(cx.tcx, cx.typing_env());
if has_interior_mutability {
return;
}

View file

@ -13,7 +13,8 @@ use rustc_hir::intravisit::{
use rustc_hir::{
BareFnTy, BodyId, FnDecl, FnSig, GenericArg, GenericArgs, GenericBound, GenericParam, GenericParamKind, Generics,
HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, Node, PolyTraitRef,
PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WhereBoundPredicate, WherePredicate, lang_items,
PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WhereBoundPredicate, WherePredicate,
WherePredicateKind, lang_items,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::hir::map::Map;
@ -443,9 +444,9 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
/// reason about elision.
fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) -> bool {
for predicate in generics.predicates {
match *predicate {
WherePredicate::RegionPredicate(..) => return true,
WherePredicate::BoundPredicate(ref pred) => {
match *predicate.kind {
WherePredicateKind::RegionPredicate(..) => return true,
WherePredicateKind::BoundPredicate(ref pred) => {
// a predicate like F: Trait or F: for<'a> Trait<'a>
let mut visitor = RefVisitor::new(cx);
// walk the type F, it may not contain LT refs
@ -468,7 +469,7 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_
}
}
},
WherePredicate::EqPredicate(ref pred) => {
WherePredicateKind::EqPredicate(ref pred) => {
let mut visitor = RefVisitor::new(cx);
walk_ty(&mut visitor, pred.lhs_ty);
walk_ty(&mut visitor, pred.rhs_ty);
@ -565,16 +566,14 @@ where
fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate<'tcx>) {
self.where_predicate_depth += 1;
if let &WherePredicate::BoundPredicate(WhereBoundPredicate {
hir_id,
if let &WherePredicateKind::BoundPredicate(WhereBoundPredicate {
bounded_ty,
bounds,
bound_generic_params,
origin: _,
span: _,
}) = predicate
}) = predicate.kind
{
self.visit_where_bound_predicate(hir_id, bounded_ty, bounds, bound_generic_params);
self.visit_where_bound_predicate(predicate.hir_id, bounded_ty, bounds, bound_generic_params);
} else {
walk_where_predicate(self, predicate);
}

View file

@ -115,11 +115,11 @@ fn is_ref_iterable<'tcx>(
.tcx
.liberate_late_bound_regions(fn_id, cx.tcx.fn_sig(fn_id).skip_binder())
&& let &[req_self_ty, req_res_ty] = &**sig.inputs_and_output
&& let param_env = cx.tcx.param_env(fn_id)
&& implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, Some(fn_id), &[])
&& let typing_env = ty::TypingEnv::non_body_analysis(cx.tcx, fn_id)
&& implements_trait_with_env(cx.tcx, typing_env, req_self_ty, trait_id, Some(fn_id), &[])
&& let Some(into_iter_ty) =
make_normalized_projection_with_regions(cx.tcx, param_env, trait_id, sym!(IntoIter), [req_self_ty])
&& let req_res_ty = normalize_with_regions(cx.tcx, param_env, req_res_ty)
make_normalized_projection_with_regions(cx.tcx, typing_env, trait_id, sym!(IntoIter), [req_self_ty])
&& let req_res_ty = normalize_with_regions(cx.tcx, typing_env, req_res_ty)
&& into_iter_ty == req_res_ty
{
let adjustments = typeck.expr_adjustments(self_arg);
@ -151,7 +151,7 @@ fn is_ref_iterable<'tcx>(
// Using by value won't consume anything
if implements_trait(cx, self_ty, trait_id, &[])
&& let Some(ty) =
make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [self_ty])
make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [self_ty])
&& ty == res_ty
{
return Some((AdjustKind::None, self_ty));
@ -168,7 +168,7 @@ fn is_ref_iterable<'tcx>(
};
if implements_trait(cx, self_ty, trait_id, &[])
&& let Some(ty) =
make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [self_ty])
make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [self_ty])
&& ty == res_ty
{
return Some((AdjustKind::reborrow(mutbl), self_ty));
@ -181,7 +181,8 @@ fn is_ref_iterable<'tcx>(
// Attempt to borrow
let self_ty = Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, self_ty, mutbl);
if implements_trait(cx, self_ty, trait_id, &[])
&& let Some(ty) = make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [self_ty])
&& let Some(ty) =
make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [self_ty])
&& ty == res_ty
{
return Some((AdjustKind::borrow(mutbl), self_ty));
@ -204,7 +205,7 @@ fn is_ref_iterable<'tcx>(
&& target != self_ty
&& implements_trait(cx, target, trait_id, &[])
&& let Some(ty) =
make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target])
make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [target])
&& ty == res_ty
{
Some((AdjustKind::auto_reborrow(mutbl), target))
@ -222,7 +223,7 @@ fn is_ref_iterable<'tcx>(
if is_copy(cx, target)
&& implements_trait(cx, target, trait_id, &[])
&& let Some(ty) =
make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target])
make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [target])
&& ty == res_ty
{
Some((AdjustKind::Deref, target))
@ -240,7 +241,7 @@ fn is_ref_iterable<'tcx>(
if self_ty.is_ref()
&& implements_trait(cx, target, trait_id, &[])
&& let Some(ty) =
make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target])
make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [target])
&& ty == res_ty
{
Some((AdjustKind::auto_borrow(mutbl), target))

View file

@ -84,7 +84,7 @@ pub(super) fn check<'tcx>(
if !prefix.is_empty()
&& (
// Precedence of internal expression is less than or equal to precedence of `&expr`.
arg_expression.precedence().order() <= PREC_PREFIX || is_range_literal(arg_expression)
arg_expression.precedence() <= PREC_PREFIX || is_range_literal(arg_expression)
)
{
arg_snip = format!("({arg_snip})").into();

View file

@ -117,7 +117,7 @@ where
// it's being passed by value.
let scrutinee = peel_hir_expr_refs(scrutinee).0;
let (scrutinee_str, _) = snippet_with_context(cx, scrutinee.span, expr_ctxt, "..", &mut app);
let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence().order() < PREC_UNAMBIGUOUS {
let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence() < PREC_UNAMBIGUOUS {
format!("({scrutinee_str})")
} else {
scrutinee_str.into()

View file

@ -148,7 +148,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
_ => {},
}
}
requires_copy |= !ty.is_copy_modulo_regions(cx.tcx, cx.param_env);
requires_copy |= !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env());
break;
}
},
@ -158,9 +158,9 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
}
if can_lint
&& (!requires_copy || arg_ty.is_copy_modulo_regions(cx.tcx, cx.param_env))
&& (!requires_copy || arg_ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()))
// This case could be handled, but a fair bit of care would need to be taken.
&& (!requires_deref || arg_ty.is_freeze(cx.tcx, cx.param_env))
&& (!requires_deref || arg_ty.is_freeze(cx.tcx, cx.typing_env()))
{
if requires_deref {
edits.push((param.span.shrink_to_lo(), "&".into()));

View file

@ -203,10 +203,11 @@ fn is_is_empty_sig(cx: &LateContext<'_>, call_id: HirId) -> bool {
fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty: Ty<'tcx>) -> bool {
if let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator)
&& let Some(into_iter_trait) = cx.tcx.get_diagnostic_item(sym::IntoIterator)
&& let Some(iter_item_ty) = make_normalized_projection(cx.tcx, cx.param_env, iter_trait, sym::Item, [iter_ty])
&& let Some(iter_item_ty) =
make_normalized_projection(cx.tcx, cx.typing_env(), iter_trait, sym::Item, [iter_ty])
&& let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, sym::Item, [collect_ty])
&& let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions(
cx.param_env,
cx.typing_env(),
Ty::new_projection_from_args(cx.tcx, into_iter_item_proj.def_id, into_iter_item_proj.args),
)
{
@ -237,7 +238,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -
)
&& let args = cx.tcx.mk_args(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))])
&& let proj_ty = Ty::new_projection_from_args(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.typing_env(), proj_ty)
{
item_ty == EarlyBinder::bind(search_ty).instantiate(cx.tcx, cx.typeck_results().node_args(call_id))
} else {

View file

@ -19,7 +19,7 @@ pub(super) fn check<'tcx>(
arg: &'tcx Expr<'_>,
) {
let typeck_results = cx.typeck_results();
let ecx = ConstEvalCtxt::with_env(cx.tcx, cx.param_env, typeck_results);
let ecx = ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), typeck_results);
if let Some(id) = typeck_results.type_dependent_def_id(expr.hir_id)
&& (cx.tcx.is_diagnostic_item(sym::cmp_ord_min, id) || cx.tcx.is_diagnostic_item(sym::cmp_ord_max, id))
{

View file

@ -578,7 +578,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
if output_ty.contains(param_ty) {
if let Ok(new_ty) = cx.tcx.try_instantiate_and_normalize_erasing_regions(
new_subst,
cx.param_env,
cx.typing_env(),
bound_fn_sig.rebind(output_ty),
) {
expr = parent_expr;

View file

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

View file

@ -1,5 +1,5 @@
use rustc_ast::visit::FnKind;
use rustc_ast::{NodeId, WherePredicate};
use rustc_ast::{NodeId, WherePredicateKind};
use rustc_data_structures::fx::FxHashMap;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::declare_lint_pass;
@ -51,8 +51,8 @@ impl EarlyLintPass for MultipleBoundLocations {
}
}
for clause in &generics.where_clause.predicates {
match clause {
WherePredicate::BoundPredicate(pred) => {
match &clause.kind {
WherePredicateKind::BoundPredicate(pred) => {
if (!pred.bound_generic_params.is_empty() || !pred.bounds.is_empty())
&& let Some(Some(bound_span)) = pred
.bounded_ty
@ -62,14 +62,14 @@ impl EarlyLintPass for MultipleBoundLocations {
emit_lint(cx, *bound_span, pred.bounded_ty.span);
}
},
WherePredicate::RegionPredicate(pred) => {
WherePredicateKind::RegionPredicate(pred) => {
if !pred.bounds.is_empty()
&& let Some(bound_span) = generic_params_with_bounds.get(&pred.lifetime.ident.name.as_str())
{
emit_lint(cx, *bound_span, pred.lifetime.ident.span);
}
},
WherePredicate::EqPredicate(_) => {},
WherePredicateKind::EqPredicate(_) => {},
}
}
}

View file

@ -80,7 +80,7 @@ impl<'tcx> intravisit::Visitor<'tcx> for MutVisitor<'_, 'tcx> {
"generally you want to avoid `&mut &mut _` if possible",
);
} else if let ty::Ref(_, ty, hir::Mutability::Mut) = self.cx.typeck_results().expr_ty(e).kind() {
if ty.peel_refs().is_sized(self.cx.tcx, self.cx.param_env) {
if ty.peel_refs().is_sized(self.cx.tcx, self.cx.typing_env()) {
span_lint_hir(
self.cx,
MUT_MUT,

View file

@ -85,8 +85,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> {
&& use_cx.same_ctxt
&& !use_cx.is_ty_unified
&& let use_node = use_cx.use_node(cx)
&& let Some(DefinedTy::Mir(ty)) = use_node.defined_ty(cx)
&& let ty::Param(ty) = *ty.value.skip_binder().kind()
&& let Some(DefinedTy::Mir { def_site_def_id: _, ty }) = use_node.defined_ty(cx)
&& let ty::Param(param_ty) = *ty.skip_binder().kind()
&& let Some((hir_id, fn_id, i)) = match use_node {
ExprUseNode::MethodArg(_, _, 0) => None,
ExprUseNode::MethodArg(hir_id, None, i) => cx
@ -112,7 +112,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> {
fn_id,
cx.typeck_results().node_args(hir_id),
i,
ty,
param_ty,
expr,
&self.msrv,
)
@ -421,7 +421,7 @@ fn replace_types<'tcx>(
.expect_ty(cx.tcx)
.to_ty(cx.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.typing_env(), projection)
&& args[term_param_ty.index as usize] != GenericArg::from(projected_ty)
{
deque.push_back((*term_param_ty, projected_ty));

View file

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then;
use rustc_errors::Applicability;
use rustc_hir::def_id::{DefId, DefIdMap};
use rustc_hir::{BoundPolarity, GenericBound, Generics, PolyTraitRef, TraitBoundModifiers, WherePredicate};
use rustc_hir::{BoundPolarity, GenericBound, Generics, PolyTraitRef, TraitBoundModifiers, WherePredicateKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{ClauseKind, PredicatePolarity};
use rustc_session::declare_lint_pass;
@ -52,7 +52,7 @@ fn type_param_bounds<'tcx>(generics: &'tcx Generics<'tcx>) -> impl Iterator<Item
.iter()
.enumerate()
.filter_map(|(predicate_pos, predicate)| {
let WherePredicate::BoundPredicate(bound_predicate) = predicate else {
let WherePredicateKind::BoundPredicate(bound_predicate) = &predicate.kind else {
return None;
};

View file

@ -180,11 +180,11 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
if !is_self(arg)
&& !ty.is_mutable_ptr()
&& !is_copy(cx, ty)
&& ty.is_sized(cx.tcx, cx.param_env)
&& ty.is_sized(cx.tcx, cx.typing_env())
&& !allowed_traits.iter().any(|&t| {
implements_trait_with_env_from_iter(cx.tcx, cx.param_env, ty, t, None, [Option::<
implements_trait_with_env_from_iter(cx.tcx, cx.typing_env(), ty, t, None, [None::<
ty::GenericArg<'tcx>,
>::None])
>])
})
&& !implements_borrow_trait
&& !all_borrowable_trait

View file

@ -58,7 +58,7 @@ fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
{
let mut applicability = Applicability::MachineApplicable;
let (snip, from_macro) = snippet_with_context(cx, exp.span, span.ctxt(), "..", &mut applicability);
let suggestion = if !from_macro && exp.precedence().order() < PREC_PREFIX && !has_enclosing_paren(&snip) {
let suggestion = if !from_macro && exp.precedence() < PREC_PREFIX && !has_enclosing_paren(&snip) {
format!("-({snip})")
} else {
format!("-{snip}")

View file

@ -270,31 +270,36 @@ impl<'tcx> NonCopyConst<'tcx> {
instance,
promoted: None,
};
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, DUMMY_SP);
let typing_env = ty::TypingEnv::post_analysis(cx.tcx, def_id);
let result = cx.tcx.const_eval_global_id_for_typeck(typing_env, cid, DUMMY_SP);
Self::is_value_unfrozen_raw(cx, result, ty)
}
fn is_value_unfrozen_expr(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool {
let args = cx.typeck_results().node_args(hir_id);
let result = Self::const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), DUMMY_SP);
let result = Self::const_eval_resolve(
cx.tcx,
cx.typing_env(),
ty::UnevaluatedConst::new(def_id, args),
DUMMY_SP,
);
Self::is_value_unfrozen_raw(cx, result, ty)
}
pub fn const_eval_resolve(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
ct: ty::UnevaluatedConst<'tcx>,
span: Span,
) -> EvalToValTreeResult<'tcx> {
match ty::Instance::try_resolve(tcx, param_env, ct.def, ct.args) {
match ty::Instance::try_resolve(tcx, typing_env, ct.def, ct.args) {
Ok(Some(instance)) => {
let cid = GlobalId {
instance,
promoted: None,
};
tcx.const_eval_global_id_for_typeck(param_env, cid, span)
tcx.const_eval_global_id_for_typeck(typing_env, cid, span)
},
Ok(None) => Err(ErrorHandled::TooGeneric(span)),
Err(err) => Err(ErrorHandled::Reported(err.into(), span)),
@ -321,7 +326,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> {
// Normalize assoc types because ones originated from generic params
// bounded other traits could have their bound.
let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
let normalized = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty);
if self.interior_mut.is_interior_mut_ty(cx, normalized)
// When there's no default value, lint it only according to its type;
// in other words, lint consts whose value *could* be unfrozen, not definitely is.
@ -361,12 +366,12 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> {
.trait_item_def_id
&& cx
.tcx
.layout_of(cx.tcx.param_env(of_trait_def_id).and(
.layout_of(ty::TypingEnv::post_analysis(cx.tcx, of_trait_def_id).as_query_input(
// Normalize assoc types because ones originated from generic params
// bounded other traits could have their bound at the trait defs;
// and, in that case, the definition is *not* generic.
cx.tcx.normalize_erasing_regions(
cx.tcx.param_env(of_trait_def_id),
ty::TypingEnv::post_analysis(cx.tcx, of_trait_def_id),
cx.tcx.type_of(of_assoc_item).instantiate_identity(),
),
))
@ -376,7 +381,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> {
// similar to unknown layouts.
// e.g. `layout_of(...).is_err() || has_frozen_variant(...);`
&& let ty = cx.tcx.type_of(impl_item.owner_id).instantiate_identity()
&& let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty)
&& let normalized = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty)
&& self.interior_mut.is_interior_mut_ty(cx, normalized)
&& Self::is_value_unfrozen_poly(cx, *body_id, normalized)
{
@ -386,7 +391,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> {
ItemKind::Impl(Impl { of_trait: None, .. }) => {
let ty = cx.tcx.type_of(impl_item.owner_id).instantiate_identity();
// Normalize assoc types originated from generic params.
let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
let normalized = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty);
if self.interior_mut.is_interior_mut_ty(cx, normalized)
&& Self::is_value_unfrozen_poly(cx, *body_id, normalized)

View file

@ -26,7 +26,7 @@ fn comparison_to_const<'tcx>(
if let ExprKind::Binary(operator, left, right) = expr.kind
&& let Ok(cmp_op) = CmpOp::try_from(operator.node)
{
let ecx = ConstEvalCtxt::with_env(cx.tcx, cx.param_env, typeck);
let ecx = ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), typeck);
match (ecx.eval(left), ecx.eval(right)) {
(Some(_), Some(_)) => None,
(_, Some(con)) => Some((cmp_op, left, right, con, typeck.expr_ty(right))),

View file

@ -39,7 +39,7 @@ fn check_op<'tcx>(
other: &Expr<'tcx>,
parent: &Expr<'tcx>,
) {
if ConstEvalCtxt::with_env(cx.tcx, cx.param_env, tck).eval_simple(op) == Some(Constant::Int(0)) {
if ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), tck).eval_simple(op) == Some(Constant::Int(0)) {
if different_types(tck, other, parent) {
return;
}

View file

@ -17,8 +17,7 @@ pub(crate) fn check<'tcx>(
right: &'tcx Expr<'_>,
) {
if (op == BinOpKind::Eq || op == BinOpKind::Ne) && is_float(cx, left) {
let typeck = cx.typeck_results();
let ecx = ConstEvalCtxt::with_env(cx.tcx, cx.param_env, typeck);
let ecx = ConstEvalCtxt::new(cx);
let left_is_local = match ecx.eval_with_source(left) {
Some((c, s)) if !is_allowed(&c) => s.is_local(),
Some(_) => return,

View file

@ -251,7 +251,7 @@ fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Ex
{
let mut applicability = Applicability::MachineApplicable;
let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability);
let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx, cx.param_env)
let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx, cx.typing_env())
&& !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..));
let sugg = if let Some(else_inner) = r#else {
if eq_expr_value(cx, caller, peel_blocks(else_inner)) {

View file

@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
let (expr_ty, expr_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(expr));
let (indexed_ty, indexed_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(indexed));
let parent_expr = get_parent_expr(cx, expr);
let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence().order() > PREC_PREFIX);
let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence() > PREC_PREFIX);
if expr_ty == indexed_ty {
if expr_ref_count > indexed_ref_count {
@ -136,7 +136,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
});
} else if let Some(target_id) = cx.tcx.lang_items().deref_target() {
if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions(
cx.param_env,
cx.typing_env(),
Ty::new_projection_from_args(cx.tcx, target_id, cx.tcx.mk_args(&[GenericArg::from(indexed_ty)])),
) {
if deref_ty == expr_ty {

View file

@ -391,7 +391,7 @@ fn check_final_expr<'tcx>(
if let Some(inner) = inner {
if for_each_unconsumed_temporary(cx, inner, |temporary_ty| {
if temporary_ty.has_significant_drop(cx.tcx, cx.param_env)
if temporary_ty.has_significant_drop(cx.tcx, cx.typing_env())
&& temporary_ty
.walk()
.any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(re) if !re.is_static()))

View file

@ -154,7 +154,7 @@ impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> {
let ty = self
.cx
.tcx
.try_normalize_erasing_regions(self.cx.param_env, ty)
.try_normalize_erasing_regions(self.cx.typing_env(), ty)
.unwrap_or(ty);
match self.type_cache.entry(ty) {
Entry::Occupied(e) => return *e.get(),

View file

@ -56,9 +56,10 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray {
fn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool {
if let ItemKind::Struct(data, _) = &item.kind
&& let Some(last_field) = data.fields().last()
&& let field_ty = cx
.tcx
.normalize_erasing_regions(cx.param_env, cx.tcx.type_of(last_field.def_id).instantiate_identity())
&& let field_ty = cx.tcx.normalize_erasing_regions(
cx.typing_env(),
cx.tcx.type_of(last_field.def_id).instantiate_identity(),
)
&& let ty::Array(_, array_len) = *field_ty.kind()
&& let Some(0) = array_len.try_to_target_usize(cx.tcx)
{

View file

@ -11,7 +11,7 @@ use rustc_errors::Applicability;
use rustc_hir::def::Res;
use rustc_hir::{
BoundPolarity, GenericBound, Generics, Item, ItemKind, LangItem, Node, Path, PathSegment, PredicateOrigin, QPath,
TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicate,
TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicateKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::impl_lint_pass;
@ -124,9 +124,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
let mut self_bounds_map = FxHashMap::default();
for predicate in item.generics.predicates {
if let WherePredicate::BoundPredicate(bound_predicate) = predicate
if let WherePredicateKind::BoundPredicate(bound_predicate) = predicate.kind
&& bound_predicate.origin != PredicateOrigin::ImplTrait
&& !bound_predicate.span.from_expansion()
&& !predicate.span.from_expansion()
&& let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind
&& let Some(PathSegment {
res: Res::SelfTyParam { trait_: def_id },
@ -268,10 +268,10 @@ impl TraitBounds {
let mut map: UnhashMap<SpanlessTy<'_, '_>, Vec<&GenericBound<'_>>> = UnhashMap::default();
let mut applicability = Applicability::MaybeIncorrect;
for bound in generics.predicates {
if let WherePredicate::BoundPredicate(p) = bound
if let WherePredicateKind::BoundPredicate(p) = bound.kind
&& p.origin != PredicateOrigin::ImplTrait
&& p.bounds.len() as u64 <= self.max_trait_bounds
&& !p.span.from_expansion()
&& !bound.span.from_expansion()
&& let bounds = p
.bounds
.iter()
@ -295,7 +295,7 @@ impl TraitBounds {
span_lint_and_help(
cx,
TYPE_REPETITION_IN_BOUNDS,
p.span,
bound.span,
"this type has already been used as a bound predicate",
None,
hint_string,
@ -322,8 +322,8 @@ fn check_trait_bound_duplication<'tcx>(cx: &LateContext<'tcx>, generics: &'_ Gen
.predicates
.iter()
.filter_map(|pred| {
if pred.in_where_clause()
&& let WherePredicate::BoundPredicate(bound_predicate) = pred
if pred.kind.in_where_clause()
&& let WherePredicateKind::BoundPredicate(bound_predicate) = pred.kind
&& let TyKind::Path(QPath::Resolved(_, path)) = bound_predicate.bounded_ty.kind
{
return Some(
@ -347,10 +347,10 @@ fn check_trait_bound_duplication<'tcx>(cx: &LateContext<'tcx>, generics: &'_ Gen
// |
// compare trait bounds keyed by generic name and comparable trait to collected where
// predicates eg. (T, Clone)
for predicate in generics.predicates.iter().filter(|pred| !pred.in_where_clause()) {
if let WherePredicate::BoundPredicate(bound_predicate) = predicate
for predicate in generics.predicates.iter().filter(|pred| !pred.kind.in_where_clause()) {
if let WherePredicateKind::BoundPredicate(bound_predicate) = predicate.kind
&& bound_predicate.origin != PredicateOrigin::ImplTrait
&& !bound_predicate.span.from_expansion()
&& !predicate.span.from_expansion()
&& let TyKind::Path(QPath::Resolved(_, path)) = bound_predicate.bounded_ty.kind
{
let traits = rollup_traits(cx, bound_predicate.bounds, "these bounds contain repeated elements");

View file

@ -88,8 +88,8 @@ pub(super) fn check<'tcx>(
&& is_normalizable(cx, cx.param_env, to_ty)
// we only want to lint if the target type has a niche that is larger than the one of the source type
// e.g. `u8` to `NonZero<u8>` should lint, but `NonZero<u8>` to `u8` should not
&& let Ok(from_layout) = cx.tcx.layout_of(cx.param_env.and(from_ty))
&& let Ok(to_layout) = cx.tcx.layout_of(cx.param_env.and(to_ty))
&& let Ok(from_layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(from_ty))
&& let Ok(to_layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(to_ty))
&& match (from_layout.largest_niche, to_layout.largest_niche) {
(Some(from_niche), Some(to_niche)) => !range_fully_contained(from_niche.valid_range, to_niche.valid_range),
(None, Some(_)) => true,

View file

@ -27,7 +27,7 @@ pub(super) fn check<'tcx>(
|diag| {
if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
if from_mutbl == to_mutbl
&& to_pointee_ty.is_sized(cx.tcx, cx.param_env)
&& to_pointee_ty.is_sized(cx.tcx, cx.typing_env())
&& msrv.meets(msrvs::POINTER_CAST)
{
diag.span_suggestion_verbose(

View file

@ -206,12 +206,12 @@ fn reduce_refs<'tcx>(cx: &LateContext<'tcx>, mut from_ty: Ty<'tcx>, mut to_ty: T
continue;
},
(&(ty::Ref(_, unsized_ty, _) | ty::RawPtr(unsized_ty, _)), _)
if !unsized_ty.is_sized(cx.tcx, cx.param_env) =>
if !unsized_ty.is_sized(cx.tcx, cx.typing_env()) =>
{
(true, false)
},
(_, &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(unsized_ty, _)))
if !unsized_ty.is_sized(cx.tcx, cx.param_env) =>
if !unsized_ty.is_sized(cx.tcx, cx.typing_env()) =>
{
(false, true)
},
@ -244,7 +244,7 @@ enum ReducedTy<'tcx> {
/// Reduce structs containing a single non-zero sized field to it's contained type.
fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> {
loop {
ty = cx.tcx.try_normalize_erasing_regions(cx.param_env, ty).unwrap_or(ty);
ty = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty).unwrap_or(ty);
return match *ty.kind() {
ty::Array(sub_ty, _) if matches!(sub_ty.kind(), ty::Int(_) | ty::Uint(_)) => {
ReducedTy::TypeErasure { raw_ptr_only: false }
@ -297,8 +297,8 @@ 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))
if let Ok(ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty)
&& let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(ty))
{
layout.layout.size().bytes() == 0
} else {

View file

@ -1,7 +1,7 @@
use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::sugg::Sugg;
use rustc_ast::ExprPrecedence;
use rustc_ast::util::parser::AssocOp;
use rustc_errors::Applicability;
use rustc_hir::{Expr, Node};
use rustc_hir_typeck::cast::check_cast;
@ -44,7 +44,8 @@ pub(super) fn check<'tcx>(
};
if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id)
&& parent.precedence().order() > ExprPrecedence::Cast.order()
&& parent.precedence()
> i8::try_from(AssocOp::As.precedence()).expect("AssocOp always returns a precedence < 128")
{
sugg = format!("({sugg})");
}

View file

@ -4,10 +4,11 @@ use rustc_middle::ty::Ty;
// check if the component types of the transmuted collection and the result have different ABI,
// size or alignment
pub(super) fn is_layout_incompatible<'tcx>(cx: &LateContext<'tcx>, from: Ty<'tcx>, to: Ty<'tcx>) -> bool {
if let Ok(from) = cx.tcx.try_normalize_erasing_regions(cx.param_env, from)
&& let Ok(to) = cx.tcx.try_normalize_erasing_regions(cx.param_env, to)
&& let Ok(from_layout) = cx.tcx.layout_of(cx.param_env.and(from))
&& let Ok(to_layout) = cx.tcx.layout_of(cx.param_env.and(to))
let typing_env = cx.typing_env();
if let Ok(from) = cx.tcx.try_normalize_erasing_regions(typing_env, from)
&& let Ok(to) = cx.tcx.try_normalize_erasing_regions(typing_env, to)
&& let Ok(from_layout) = cx.tcx.layout_of(typing_env.as_query_input(from))
&& let Ok(to_layout) = cx.tcx.layout_of(typing_env.as_query_input(to))
{
from_layout.size != to_layout.size || from_layout.align.abi != to_layout.align.abi
} else {

View file

@ -60,7 +60,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, qpath:
// here because `mod.rs` guarantees this lint is only run on types outside of bodies and
// is not run on locals.
let ty = lower_ty(cx.tcx, hir_ty);
if ty.has_escaping_bound_vars() || !ty.is_sized(cx.tcx, cx.param_env) {
if ty.has_escaping_bound_vars() || !ty.is_sized(cx.tcx, cx.typing_env()) {
return false;
}
hir_ty.span

View file

@ -37,7 +37,7 @@ pub(super) fn check<'tcx>(
&& let boxed_alloc_ty = last.args.get(1)
&& let ty_ty = lower_ty(cx.tcx, boxed_ty)
&& !ty_ty.has_escaping_bound_vars()
&& ty_ty.is_sized(cx.tcx, cx.param_env)
&& ty_ty.is_sized(cx.tcx, cx.typing_env())
&& let Ok(ty_ty_size) = cx.layout_of(ty_ty).map(|l| l.size.bytes())
&& ty_ty_size < box_size_threshold
// https://github.com/rust-lang/rust-clippy/issues/7114

View file

@ -46,7 +46,7 @@ impl LateLintPass<'_> for UninhabitedReferences {
if let ExprKind::Unary(UnOp::Deref, _) = expr.kind {
let ty = cx.typeck_results().expr_ty_adjusted(expr);
if ty.is_privately_uninhabited(cx.tcx, cx.param_env) {
if ty.is_privately_uninhabited(cx.tcx, cx.typing_env()) {
span_lint(
cx,
UNINHABITED_REFERENCES,
@ -71,7 +71,7 @@ impl LateLintPass<'_> for UninhabitedReferences {
}
if let FnRetTy::Return(hir_ty) = fndecl.output
&& let TyKind::Ref(_, mut_ty) = hir_ty.kind
&& lower_ty(cx.tcx, mut_ty.ty).is_privately_uninhabited(cx.tcx, cx.param_env)
&& lower_ty(cx.tcx, mut_ty.ty).is_privately_uninhabited(cx.tcx, cx.typing_env())
{
span_lint(
cx,

View file

@ -82,7 +82,7 @@ impl UnnecessaryBoxReturns {
// It's sometimes useful to return Box<T> if T is unsized, so don't lint those.
// Also, don't lint if we know that T is very large, in which case returning
// a Box<T> may be beneficial.
if boxed_ty.is_sized(cx.tcx, cx.param_env) && approx_ty_size(cx, boxed_ty) <= self.maximum_size {
if boxed_ty.is_sized(cx.tcx, cx.typing_env()) && approx_ty_size(cx, boxed_ty) <= self.maximum_size {
span_lint_and_then(
cx,
UNNECESSARY_BOX_RETURNS,

View file

@ -5,8 +5,8 @@ use rustc_hir as hir;
use rustc_hir::Item;
use rustc_hir::def::DefKind;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::FloatTy;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::{self, FloatTy};
use rustc_session::declare_lint_pass;
use rustc_span::symbol::Symbol;
@ -32,9 +32,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidPaths {
let mod_name = &cx.tcx.item_name(local_def_id.to_def_id());
if mod_name.as_str() == "paths"
&& let hir::ItemKind::Const(.., body_id) = item.kind
&& let Some(Constant::Vec(path)) =
ConstEvalCtxt::with_env(cx.tcx, cx.tcx.param_env(item.owner_id), cx.tcx.typeck(item.owner_id))
.eval_simple(cx.tcx.hir().body(body_id).value)
&& let Some(Constant::Vec(path)) = ConstEvalCtxt::with_env(
cx.tcx,
ty::TypingEnv::post_analysis(cx.tcx, item.owner_id),
cx.tcx.typeck(item.owner_id),
)
.eval_simple(cx.tcx.hir().body(body_id).value)
&& let Some(path) = path
.iter()
.map(|x| {

View file

@ -1,7 +1,7 @@
[package]
name = "clippy_utils"
# begin autogenerated version
version = "0.1.84"
version = "0.1.85"
# end autogenerated version
edition = "2021"
description = "Helpful tools for writing lints, provided as they are used in Clippy"

View file

@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain:
<!-- begin autogenerated nightly -->
```
nightly-2024-11-14
nightly-2024-11-28
```
<!-- end autogenerated nightly -->

View file

@ -661,8 +661,8 @@ pub fn eq_generics(l: &Generics, r: &Generics) -> bool {
}
pub fn eq_where_predicate(l: &WherePredicate, r: &WherePredicate) -> bool {
use WherePredicate::*;
match (l, r) {
use WherePredicateKind::*;
match (&l.kind, &r.kind) {
(BoundPredicate(l), BoundPredicate(r)) => {
over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
eq_generic_param(l, r)

View file

@ -18,7 +18,7 @@ use rustc_lexer::tokenize;
use rustc_lint::LateContext;
use rustc_middle::mir::ConstValue;
use rustc_middle::mir::interpret::{Scalar, alloc_range};
use rustc_middle::ty::{self, FloatTy, IntTy, ParamEnv, ScalarInt, Ty, TyCtxt, TypeckResults, UintTy};
use rustc_middle::ty::{self, FloatTy, IntTy, ScalarInt, Ty, TyCtxt, TypeckResults, UintTy};
use rustc_middle::{bug, mir, span_bug};
use rustc_span::def_id::DefId;
use rustc_span::symbol::Ident;
@ -387,7 +387,7 @@ impl Ord for FullInt {
/// See the module level documentation for some context.
pub struct ConstEvalCtxt<'tcx> {
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
typeck: &'tcx TypeckResults<'tcx>,
source: Cell<ConstantSource>,
}
@ -398,17 +398,17 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
pub fn new(cx: &LateContext<'tcx>) -> Self {
Self {
tcx: cx.tcx,
param_env: cx.param_env,
typing_env: cx.typing_env(),
typeck: cx.typeck_results(),
source: Cell::new(ConstantSource::Local),
}
}
/// Creates an evaluation context.
pub fn with_env(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, typeck: &'tcx TypeckResults<'tcx>) -> Self {
pub fn with_env(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, typeck: &'tcx TypeckResults<'tcx>) -> Self {
Self {
tcx,
param_env,
typing_env,
typeck,
source: Cell::new(ConstantSource::Local),
}
@ -643,7 +643,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
let args = self.typeck.node_args(id);
let result = self
.tcx
.const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), qpath.span())
.const_eval_resolve(self.typing_env, mir::UnevaluatedConst::new(def_id, args), qpath.span())
.ok()
.map(|val| mir::Const::from_value(val, ty))?;
f(self, result)

View file

@ -105,7 +105,7 @@ fn res_has_significant_drop(res: Res, cx: &LateContext<'_>, e: &Expr<'_>) -> boo
{
cx.typeck_results()
.expr_ty(e)
.has_significant_drop(cx.tcx, cx.param_env)
.has_significant_drop(cx.tcx, cx.typing_env())
} else {
false
}

View file

@ -297,8 +297,8 @@ impl HirEqInterExpr<'_, '_, '_> {
if let Some((typeck_lhs, typeck_rhs)) = self.inner.maybe_typeck_results
&& typeck_lhs.expr_ty(left) == typeck_rhs.expr_ty(right)
&& let (Some(l), Some(r)) = (
ConstEvalCtxt::with_env(self.inner.cx.tcx, self.inner.cx.param_env, typeck_lhs).eval_simple(left),
ConstEvalCtxt::with_env(self.inner.cx.tcx, self.inner.cx.param_env, typeck_rhs).eval_simple(right),
ConstEvalCtxt::with_env(self.inner.cx.tcx, self.inner.cx.typing_env(), typeck_lhs).eval_simple(left),
ConstEvalCtxt::with_env(self.inner.cx.tcx, self.inner.cx.typing_env(), typeck_rhs).eval_simple(right),
)
&& l == r
{
@ -738,7 +738,7 @@ pub fn over<X>(left: &[X], right: &[X], mut eq_fn: impl FnMut(&X, &X) -> bool) -
left.len() == right.len() && left.iter().zip(right).all(|(x, y)| eq_fn(x, y))
}
/// Counts how many elements at the beginning of the slices are equal as per `eq_fn`.
/// Counts how many elements of the slices are equal as per `eq_fn`.
pub fn count_eq<X: Sized>(
left: &mut dyn Iterator<Item = X>,
right: &mut dyn Iterator<Item = X>,
@ -819,7 +819,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
#[expect(clippy::too_many_lines)]
pub fn hash_expr(&mut self, e: &Expr<'_>) {
let simple_const = self.maybe_typeck_results.and_then(|typeck_results| {
ConstEvalCtxt::with_env(self.cx.tcx, self.cx.param_env, typeck_results).eval_simple(e)
ConstEvalCtxt::with_env(self.cx.tcx, self.cx.typing_env(), typeck_results).eval_simple(e)
});
// const hashing may result in the same hash as some unrelated node, so add a sort of

View file

@ -117,8 +117,8 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::{
self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgsRef, IntTy, ParamEnv,
ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt, UintTy, UpvarCapture,
self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgsRef, IntTy, Ty, TyCtxt,
TypeVisitableExt, UintTy, UpvarCapture,
};
use rustc_span::hygiene::{ExpnKind, MacroKind};
use rustc_span::source_map::SourceMap;
@ -1620,7 +1620,7 @@ pub fn is_integer_const(cx: &LateContext<'_>, e: &Expr<'_>, value: u128) -> bool
}
let enclosing_body = cx.tcx.hir().enclosing_body_owner(e.hir_id);
if let Some(Constant::Int(v)) =
ConstEvalCtxt::with_env(cx.tcx, cx.tcx.param_env(enclosing_body), cx.tcx.typeck(enclosing_body)).eval(e)
ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), cx.tcx.typeck(enclosing_body)).eval(e)
{
return value == v;
}
@ -2701,9 +2701,17 @@ pub fn walk_to_expr_usage<'tcx, T>(
pub enum DefinedTy<'tcx> {
// Used for locals and closures defined within the function.
Hir(&'tcx hir::Ty<'tcx>),
/// Used for function signatures, and constant and static values. This includes the `ParamEnv`
/// from the definition site.
Mir(ParamEnvAnd<'tcx, Binder<'tcx, Ty<'tcx>>>),
/// Used for function signatures, and constant and static values. The type is
/// in the context of its definition site. We also track the `def_id` of its
/// definition site.
///
/// WARNING: As the `ty` in in the scope of the definition, not of the function
/// using it, you must be very careful with how you use it. Using it in the wrong
/// scope easily results in ICEs.
Mir {
def_site_def_id: Option<DefId>,
ty: Binder<'tcx, Ty<'tcx>>,
},
}
/// The context an expressions value is used in.
@ -2822,10 +2830,10 @@ impl<'tcx> ExprUseNode<'tcx> {
pub fn defined_ty(&self, cx: &LateContext<'tcx>) -> Option<DefinedTy<'tcx>> {
match *self {
Self::LetStmt(LetStmt { ty: Some(ty), .. }) => Some(DefinedTy::Hir(ty)),
Self::ConstStatic(id) => Some(DefinedTy::Mir(
cx.param_env
.and(Binder::dummy(cx.tcx.type_of(id).instantiate_identity())),
)),
Self::ConstStatic(id) => Some(DefinedTy::Mir {
def_site_def_id: Some(id.def_id.to_def_id()),
ty: Binder::dummy(cx.tcx.type_of(id).instantiate_identity()),
}),
Self::Return(id) => {
if let Node::Expr(Expr {
kind: ExprKind::Closure(c),
@ -2837,9 +2845,11 @@ impl<'tcx> ExprUseNode<'tcx> {
FnRetTy::Return(ty) => Some(DefinedTy::Hir(ty)),
}
} else {
Some(DefinedTy::Mir(
cx.param_env.and(cx.tcx.fn_sig(id).instantiate_identity().output()),
))
let ty = cx.tcx.fn_sig(id).instantiate_identity().output();
Some(DefinedTy::Mir {
def_site_def_id: Some(id.def_id.to_def_id()),
ty,
})
}
},
Self::Field(field) => match get_parent_expr_for_hir(cx, field.hir_id) {
@ -2855,12 +2865,9 @@ impl<'tcx> ExprUseNode<'tcx> {
.find(|f| f.name == field.ident.name)
.map(|f| (adt, f))
})
.map(|(adt, field_def)| {
DefinedTy::Mir(
cx.tcx
.param_env(adt.did())
.and(Binder::dummy(cx.tcx.type_of(field_def.did).instantiate_identity())),
)
.map(|(adt, field_def)| DefinedTy::Mir {
def_site_def_id: Some(adt.did()),
ty: Binder::dummy(cx.tcx.type_of(field_def.did).instantiate_identity()),
}),
_ => None,
},
@ -2869,17 +2876,19 @@ impl<'tcx> ExprUseNode<'tcx> {
let (hir_ty, ty) = sig.input_with_hir(i)?;
Some(match hir_ty {
Some(hir_ty) => DefinedTy::Hir(hir_ty),
None => DefinedTy::Mir(
sig.predicates_id()
.map_or(ParamEnv::empty(), |id| cx.tcx.param_env(id))
.and(ty),
),
None => DefinedTy::Mir {
def_site_def_id: sig.predicates_id(),
ty,
},
})
},
Self::MethodArg(id, _, i) => {
let id = cx.typeck_results().type_dependent_def_id(id)?;
let sig = cx.tcx.fn_sig(id).skip_binder();
Some(DefinedTy::Mir(cx.tcx.param_env(id).and(sig.input(i))))
Some(DefinedTy::Mir {
def_site_def_id: Some(id),
ty: sig.input(i),
})
},
Self::LetStmt(_) | Self::FieldAccess(..) | Self::Callee | Self::Other | Self::AddrOf(..) => None,
}

View file

@ -142,7 +142,7 @@ fn check_rvalue<'tcx>(
// We cannot allow this for now.
return Err((span, "unsizing casts are only allowed for references right now".into()));
};
let unsized_ty = tcx.struct_tail_for_codegen(pointee_ty, tcx.param_env(def_id));
let unsized_ty = tcx.struct_tail_for_codegen(pointee_ty, ty::TypingEnv::post_analysis(tcx, def_id));
if let ty::Slice(_) | ty::Str = unsized_ty.kind() {
check_operand(tcx, op, span, body, msrv)?;
// Casting/coercing things to slices is fine.
@ -233,6 +233,7 @@ fn check_statement<'tcx>(
| StatementKind::PlaceMention(..)
| StatementKind::Coverage(..)
| StatementKind::ConstEvalCounter
| StatementKind::BackwardIncompatibleDropHint { .. }
| StatementKind::Nop => Ok(()),
}
}
@ -403,20 +404,20 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
// FIXME(const_trait_impl, fee1-dead) revert to const destruct once it works again
#[expect(unused)]
fn is_ty_const_destruct_unused<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>) -> bool {
// Avoid selecting for simple cases, such as builtin types.
if ty::util::is_trivially_const_drop(ty) {
return true;
// If this doesn't need drop at all, then don't select `~const Destruct`.
if !ty.needs_drop(tcx, body.typing_env(tcx)) {
return false;
}
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(body.typing_env(tcx));
// FIXME(const_trait_impl) constness
let obligation = Obligation::new(
tcx,
ObligationCause::dummy_with_span(body.span),
ConstCx::new(tcx, body).param_env,
param_env,
TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, Some(body.span)), [ty]),
);
let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx));
let mut selcx = SelectionContext::new(&infcx);
let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {
return false;
@ -434,5 +435,5 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
ocx.select_all_or_error().is_empty()
}
!ty.needs_drop(tcx, ConstCx::new(tcx, body).param_env)
!ty.needs_drop(tcx, ConstCx::new(tcx, body).typing_env)
}

View file

@ -19,7 +19,7 @@ use rustc_middle::ty::layout::ValidityRequirement;
use rustc_middle::ty::{
self, AdtDef, AliasTy, AssocItem, AssocKind, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind,
GenericArgsRef, GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable,
TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, UintTy, Upcast, VariantDef, VariantDiscr,
TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,
};
use rustc_span::symbol::Ident;
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
@ -38,7 +38,7 @@ pub use type_certainty::expr_type_is_certain;
/// Checks if the given type implements copy.
pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
ty.is_copy_modulo_regions(cx.tcx, cx.param_env)
ty.is_copy_modulo_regions(cx.tcx, cx.typing_env())
}
/// This checks whether a given type is known to implement Debug.
@ -226,7 +226,14 @@ pub fn implements_trait<'tcx>(
trait_id: DefId,
args: &[GenericArg<'tcx>],
) -> bool {
implements_trait_with_env_from_iter(cx.tcx, cx.param_env, ty, trait_id, None, args.iter().map(|&x| Some(x)))
implements_trait_with_env_from_iter(
cx.tcx,
cx.typing_env(),
ty,
trait_id,
None,
args.iter().map(|&x| Some(x)),
)
}
/// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
@ -235,19 +242,19 @@ pub fn implements_trait<'tcx>(
/// environment, used for checking const traits.
pub fn implements_trait_with_env<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>,
trait_id: DefId,
callee_id: Option<DefId>,
args: &[GenericArg<'tcx>],
) -> bool {
implements_trait_with_env_from_iter(tcx, param_env, ty, trait_id, callee_id, args.iter().map(|&x| Some(x)))
implements_trait_with_env_from_iter(tcx, typing_env, ty, trait_id, callee_id, args.iter().map(|&x| Some(x)))
}
/// Same as `implements_trait_from_env` but takes the arguments as an iterator.
pub fn implements_trait_with_env_from_iter<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>,
trait_id: DefId,
callee_id: Option<DefId>,
@ -268,7 +275,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
return false;
}
let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(param_env));
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
let args = args
.into_iter()
.map(|arg| arg.into().unwrap_or_else(|| infcx.next_ty_var(DUMMY_SP).into()))
@ -467,7 +474,7 @@ pub fn needs_ordered_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
if !seen.insert(ty) {
return false;
}
if !ty.has_significant_drop(cx.tcx, cx.param_env) {
if !ty.has_significant_drop(cx.tcx, cx.typing_env()) {
false
}
// Check for std types which implement drop, but only for memory allocation.
@ -575,8 +582,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<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
let typing_env = cx.typing_env().with_post_analysis_normalized(cx.tcx);
cx.tcx
.check_validity_requirement((ValidityRequirement::Uninit, cx.param_env.and(ty)))
.check_validity_requirement((ValidityRequirement::Uninit, typing_env.as_query_input(ty)))
.unwrap_or_else(|_| is_uninit_value_valid_for_ty_fallback(cx, ty))
}
@ -725,7 +733,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
_ => None,
}
},
ty::Alias(ty::Projection, proj) => match cx.tcx.try_normalize_erasing_regions(cx.param_env, ty) {
ty::Alias(ty::Projection, proj) => match cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty) {
Ok(normalized_ty) if normalized_ty != ty => ty_sig(cx, normalized_ty),
_ => sig_for_projection(cx, proj).or_else(|| sig_from_bounds(cx, ty, cx.param_env.caller_bounds(), None)),
},
@ -1111,12 +1119,12 @@ pub fn make_projection<'tcx>(
/// succeeds as well as everything checked by `make_projection`.
pub fn make_normalized_projection<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
container_id: DefId,
assoc_ty: Symbol,
args: impl IntoIterator<Item = impl Into<GenericArg<'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>, typing_env: ty::TypingEnv<'tcx>, ty: AliasTy<'tcx>) -> Option<Ty<'tcx>> {
#[cfg(debug_assertions)]
if let Some((i, arg)) = ty
.args
@ -1132,7 +1140,7 @@ pub fn make_normalized_projection<'tcx>(
);
return None;
}
match tcx.try_normalize_erasing_regions(param_env, Ty::new_projection_from_args(tcx, ty.def_id, ty.args)) {
match tcx.try_normalize_erasing_regions(typing_env, Ty::new_projection_from_args(tcx, ty.def_id, ty.args)) {
Ok(ty) => Some(ty),
Err(e) => {
debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}");
@ -1140,7 +1148,7 @@ pub fn make_normalized_projection<'tcx>(
},
}
}
helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, args)?)
helper(tcx, typing_env, make_projection(tcx, container_id, assoc_ty, args)?)
}
/// Helper to check if given type has inner mutability such as [`std::cell::Cell`] or
@ -1238,12 +1246,12 @@ impl<'tcx> InteriorMut<'tcx> {
pub fn make_normalized_projection_with_regions<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
container_id: DefId,
assoc_ty: Symbol,
args: impl IntoIterator<Item = impl Into<GenericArg<'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>, typing_env: ty::TypingEnv<'tcx>, ty: AliasTy<'tcx>) -> Option<Ty<'tcx>> {
#[cfg(debug_assertions)]
if let Some((i, arg)) = ty
.args
@ -1260,9 +1268,8 @@ pub fn make_normalized_projection_with_regions<'tcx>(
return None;
}
let cause = ObligationCause::dummy();
match tcx
.infer_ctxt()
.build(TypingMode::from_param_env(param_env))
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
match infcx
.at(&cause, param_env)
.query_normalize(Ty::new_projection_from_args(tcx, ty.def_id, ty.args))
{
@ -1273,20 +1280,16 @@ pub fn make_normalized_projection_with_regions<'tcx>(
},
}
}
helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, args)?)
helper(tcx, typing_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>, typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
let cause = ObligationCause::dummy();
match tcx
.infer_ctxt()
.build(TypingMode::from_param_env(param_env))
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
infcx
.at(&cause, param_env)
.query_normalize(ty)
{
Ok(ty) => ty.value,
Err(_) => ty,
}
.map_or(ty, |ty| ty.value)
}
/// Checks if the type is `core::mem::ManuallyDrop<_>`
@ -1300,7 +1303,7 @@ pub fn deref_chain<'cx, 'tcx>(cx: &'cx LateContext<'tcx>, ty: Ty<'tcx>) -> impl
if let Some(deref_did) = cx.tcx.lang_items().deref_trait()
&& implements_trait(cx, ty, deref_did, &[])
{
make_normalized_projection(cx.tcx, cx.param_env, deref_did, sym::Target, [ty])
make_normalized_projection(cx.tcx, cx.typing_env(), deref_did, sym::Target, [ty])
} else {
None
}

View file

@ -1,6 +1,6 @@
[toolchain]
# begin autogenerated nightly
channel = "nightly-2024-11-14"
channel = "nightly-2024-11-28"
# end autogenerated nightly
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
profile = "minimal"