1
Fork 0

remove TypingMode::from_param_env in clippy

This commit is contained in:
lcnr 2024-11-19 19:31:02 +01:00
parent 4813fda2e6
commit d667dd5677
7 changed files with 77 additions and 68 deletions

View file

@ -15,6 +15,7 @@ use rustc_hir::{
self as hir, BindingMode, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node, Pat, self as hir, BindingMode, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node, Pat,
PatKind, Path, QPath, TyKind, UnOp, PatKind, Path, QPath, TyKind, UnOp,
}; };
use rustc_hir::def_id::DefId;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeckResults}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeckResults};
@ -753,11 +754,10 @@ impl TyCoercionStability {
fn for_defined_ty<'tcx>(cx: &LateContext<'tcx>, ty: DefinedTy<'tcx>, for_return: bool) -> Self { fn for_defined_ty<'tcx>(cx: &LateContext<'tcx>, ty: DefinedTy<'tcx>, for_return: bool) -> Self {
match ty { match ty {
DefinedTy::Hir(ty) => Self::for_hir_ty(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, cx.tcx,
// FIXME(#132279): convert `DefinedTy` to use `TypingEnv` instead. def_site_def_id,
ty::TypingEnv::from_param_env(ty.param_env), cx.tcx.instantiate_bound_regions_with_erased(ty),
cx.tcx.instantiate_bound_regions_with_erased(ty.value),
for_return, for_return,
), ),
} }
@ -824,12 +824,15 @@ impl TyCoercionStability {
} }
} }
fn for_mir_ty<'tcx>(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'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 { let ty::Ref(_, mut ty, _) = *ty.kind() else {
return Self::None; return Self::None;
}; };
ty = tcx.try_normalize_erasing_regions(typing_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 { loop {
break match *ty.kind() { break match *ty.kind() {
ty::Ref(_, ref_ty, _) => { ty::Ref(_, ref_ty, _) => {

View file

@ -454,13 +454,13 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
&& cx.tcx.is_diagnostic_item(sym::PartialEq, def_id) && cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)
&& !has_non_exhaustive_attr(cx.tcx, *adt) && !has_non_exhaustive_attr(cx.tcx, *adt)
&& !ty_implements_eq_trait(cx.tcx, ty, eq_trait_def_id) && !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() && let Some(local_def_id) = adt.did().as_local()
// If all of our fields implement `Eq`, we can implement `Eq` too // If all of our fields implement `Eq`, we can implement `Eq` too
&& adt && adt
.all_fields() .all_fields()
.map(|f| f.ty(cx.tcx, args)) .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( span_lint_hir_and_then(
cx, cx,
@ -485,7 +485,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. /// 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. // Initial map from generic index to param def.
// Vec<(param_def, needs_eq)> // Vec<(param_def, needs_eq)>
let mut params = tcx let mut params = tcx
@ -506,7 +506,7 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) ->
} }
} }
ParamEnv::new( let param_env = ParamEnv::new(
tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain( tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain(
params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {
ClauseKind::Trait(TraitPredicate { ClauseKind::Trait(TraitPredicate {
@ -517,5 +517,9 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) ->
}), }),
)), )),
Reveal::UserFacing, Reveal::UserFacing,
) );
ty::TypingEnv {
typing_mode: ty::TypingMode::non_body_analysis(),
param_env,
}
} }

View file

@ -115,11 +115,11 @@ fn is_ref_iterable<'tcx>(
.tcx .tcx
.liberate_late_bound_regions(fn_id, cx.tcx.fn_sig(fn_id).skip_binder()) .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 &[req_self_ty, req_res_ty] = &**sig.inputs_and_output
&& let param_env = cx.tcx.param_env(fn_id) && let typing_env = ty::TypingEnv::non_body_analysis(cx.tcx, fn_id)
&& implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, Some(fn_id), &[]) && implements_trait_with_env(cx.tcx, typing_env, req_self_ty, trait_id, Some(fn_id), &[])
&& let Some(into_iter_ty) = && let Some(into_iter_ty) =
make_normalized_projection_with_regions(cx.tcx, param_env, trait_id, sym!(IntoIter), [req_self_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, param_env, req_res_ty) && let req_res_ty = normalize_with_regions(cx.tcx, typing_env, req_res_ty)
&& into_iter_ty == req_res_ty && into_iter_ty == req_res_ty
{ {
let adjustments = typeck.expr_adjustments(self_arg); let adjustments = typeck.expr_adjustments(self_arg);

View file

@ -85,8 +85,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> {
&& use_cx.same_ctxt && use_cx.same_ctxt
&& !use_cx.is_ty_unified && !use_cx.is_ty_unified
&& let use_node = use_cx.use_node(cx) && let use_node = use_cx.use_node(cx)
&& let Some(DefinedTy::Mir(ty)) = use_node.defined_ty(cx) && let Some(DefinedTy::Mir { def_site_def_id: _, ty }) = use_node.defined_ty(cx)
&& let ty::Param(ty) = *ty.value.skip_binder().kind() && let ty::Param(param_ty) = *ty.skip_binder().kind()
&& let Some((hir_id, fn_id, i)) = match use_node { && let Some((hir_id, fn_id, i)) = match use_node {
ExprUseNode::MethodArg(_, _, 0) => None, ExprUseNode::MethodArg(_, _, 0) => None,
ExprUseNode::MethodArg(hir_id, None, i) => cx ExprUseNode::MethodArg(hir_id, None, i) => cx
@ -112,7 +112,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> {
fn_id, fn_id,
cx.typeck_results().node_args(hir_id), cx.typeck_results().node_args(hir_id),
i, i,
ty, param_ty,
expr, expr,
&self.msrv, &self.msrv,
) )

View file

@ -182,9 +182,14 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
&& !is_copy(cx, ty) && !is_copy(cx, ty)
&& ty.is_sized(cx.tcx, cx.typing_env()) && ty.is_sized(cx.tcx, cx.typing_env())
&& !allowed_traits.iter().any(|&t| { && !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(
ty::GenericArg<'tcx>, cx.tcx,
>::None]) cx.typing_env(),
ty,
t,
None,
[None::<ty::GenericArg<'tcx>>]
)
}) })
&& !implements_borrow_trait && !implements_borrow_trait
&& !all_borrowable_trait && !all_borrowable_trait

View file

@ -116,8 +116,8 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::{ use rustc_middle::ty::{
self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgsRef, IntTy, ParamEnv, self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgsRef, IntTy,
ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt, UintTy, UpvarCapture, Ty, TyCtxt, TypeVisitableExt, UintTy, UpvarCapture,
}; };
use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::hygiene::{ExpnKind, MacroKind};
use rustc_span::source_map::SourceMap; use rustc_span::source_map::SourceMap;
@ -2712,9 +2712,17 @@ pub fn walk_to_expr_usage<'tcx, T>(
pub enum DefinedTy<'tcx> { pub enum DefinedTy<'tcx> {
// Used for locals and closures defined within the function. // Used for locals and closures defined within the function.
Hir(&'tcx hir::Ty<'tcx>), Hir(&'tcx hir::Ty<'tcx>),
/// Used for function signatures, and constant and static values. This includes the `ParamEnv` /// Used for function signatures, and constant and static values. The type is
/// from the definition site. /// in the context of its definition site. We also track the `def_id` of its
Mir(ParamEnvAnd<'tcx, Binder<'tcx, Ty<'tcx>>>), /// 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. /// The context an expressions value is used in.
@ -2833,10 +2841,10 @@ impl<'tcx> ExprUseNode<'tcx> {
pub fn defined_ty(&self, cx: &LateContext<'tcx>) -> Option<DefinedTy<'tcx>> { pub fn defined_ty(&self, cx: &LateContext<'tcx>) -> Option<DefinedTy<'tcx>> {
match *self { match *self {
Self::LetStmt(LetStmt { ty: Some(ty), .. }) => Some(DefinedTy::Hir(ty)), Self::LetStmt(LetStmt { ty: Some(ty), .. }) => Some(DefinedTy::Hir(ty)),
Self::ConstStatic(id) => Some(DefinedTy::Mir( Self::ConstStatic(id) => Some(DefinedTy::Mir {
cx.param_env def_site_def_id: Some(id.def_id.to_def_id()),
.and(Binder::dummy(cx.tcx.type_of(id).instantiate_identity())), ty: Binder::dummy(cx.tcx.type_of(id).instantiate_identity()),
)), }),
Self::Return(id) => { Self::Return(id) => {
if let Node::Expr(Expr { if let Node::Expr(Expr {
kind: ExprKind::Closure(c), kind: ExprKind::Closure(c),
@ -2848,9 +2856,8 @@ impl<'tcx> ExprUseNode<'tcx> {
FnRetTy::Return(ty) => Some(DefinedTy::Hir(ty)), FnRetTy::Return(ty) => Some(DefinedTy::Hir(ty)),
} }
} else { } else {
Some(DefinedTy::Mir( let ty = cx.tcx.fn_sig(id).instantiate_identity().output();
cx.param_env.and(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) { Self::Field(field) => match get_parent_expr_for_hir(cx, field.hir_id) {
@ -2866,12 +2873,9 @@ impl<'tcx> ExprUseNode<'tcx> {
.find(|f| f.name == field.ident.name) .find(|f| f.name == field.ident.name)
.map(|f| (adt, f)) .map(|f| (adt, f))
}) })
.map(|(adt, field_def)| { .map(|(adt, field_def)| DefinedTy::Mir {
DefinedTy::Mir( def_site_def_id: Some(adt.did()),
cx.tcx ty: Binder::dummy(cx.tcx.type_of(field_def.did).instantiate_identity()),
.param_env(adt.did())
.and(Binder::dummy(cx.tcx.type_of(field_def.did).instantiate_identity())),
)
}), }),
_ => None, _ => None,
}, },
@ -2880,17 +2884,19 @@ impl<'tcx> ExprUseNode<'tcx> {
let (hir_ty, ty) = sig.input_with_hir(i)?; let (hir_ty, ty) = sig.input_with_hir(i)?;
Some(match hir_ty { Some(match hir_ty {
Some(hir_ty) => DefinedTy::Hir(hir_ty), Some(hir_ty) => DefinedTy::Hir(hir_ty),
None => DefinedTy::Mir( None => DefinedTy::Mir {
sig.predicates_id() def_site_def_id: sig.predicates_id(),
.map_or(ParamEnv::empty(), |id| cx.tcx.param_env(id)) ty,
.and(ty), }
),
}) })
}, },
Self::MethodArg(id, _, i) => { Self::MethodArg(id, _, i) => {
let id = cx.typeck_results().type_dependent_def_id(id)?; let id = cx.typeck_results().type_dependent_def_id(id)?;
let sig = cx.tcx.fn_sig(id).skip_binder(); 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, Self::LetStmt(_) | Self::FieldAccess(..) | Self::Callee | Self::Other | Self::AddrOf(..) => None,
} }

View file

@ -19,7 +19,7 @@ use rustc_middle::ty::layout::ValidityRequirement;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AdtDef, AliasTy, AssocItem, AssocKind, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind, self, AdtDef, AliasTy, AssocItem, AssocKind, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind,
GenericArgsRef, GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, 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::symbol::Ident;
use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use rustc_span::{DUMMY_SP, Span, Symbol, sym};
@ -226,7 +226,7 @@ pub fn implements_trait<'tcx>(
trait_id: DefId, trait_id: DefId,
args: &[GenericArg<'tcx>], args: &[GenericArg<'tcx>],
) -> bool { ) -> 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. /// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
@ -235,19 +235,19 @@ pub fn implements_trait<'tcx>(
/// environment, used for checking const traits. /// environment, used for checking const traits.
pub fn implements_trait_with_env<'tcx>( pub fn implements_trait_with_env<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
trait_id: DefId, trait_id: DefId,
callee_id: Option<DefId>, callee_id: Option<DefId>,
args: &[GenericArg<'tcx>], args: &[GenericArg<'tcx>],
) -> bool { ) -> 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. /// Same as `implements_trait_from_env` but takes the arguments as an iterator.
pub fn implements_trait_with_env_from_iter<'tcx>( pub fn implements_trait_with_env_from_iter<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
trait_id: DefId, trait_id: DefId,
callee_id: Option<DefId>, callee_id: Option<DefId>,
@ -268,7 +268,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
return false; 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 let args = args
.into_iter() .into_iter()
.map(|arg| arg.into().unwrap_or_else(|| infcx.next_ty_var(DUMMY_SP).into())) .map(|arg| arg.into().unwrap_or_else(|| infcx.next_ty_var(DUMMY_SP).into()))
@ -1239,12 +1239,12 @@ impl<'tcx> InteriorMut<'tcx> {
pub fn make_normalized_projection_with_regions<'tcx>( pub fn make_normalized_projection_with_regions<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
container_id: DefId, container_id: DefId,
assoc_ty: Symbol, assoc_ty: Symbol,
args: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, args: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
) -> Option<Ty<'tcx>> { ) -> Option<Ty<'tcx>> {
fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>) -> Option<Ty<'tcx>> { fn helper<'tcx>(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, ty: AliasTy<'tcx>) -> Option<Ty<'tcx>> {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
if let Some((i, arg)) = ty if let Some((i, arg)) = ty
.args .args
@ -1261,10 +1261,8 @@ pub fn make_normalized_projection_with_regions<'tcx>(
return None; return None;
} }
let cause = ObligationCause::dummy(); let cause = ObligationCause::dummy();
match tcx let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
.infer_ctxt() match infcx.at(&cause, param_env)
.build(TypingMode::from_param_env(param_env))
.at(&cause, param_env)
.query_normalize(Ty::new_projection_from_args(tcx, ty.def_id, ty.args)) .query_normalize(Ty::new_projection_from_args(tcx, ty.def_id, ty.args))
{ {
Ok(ty) => Some(ty.value), Ok(ty) => Some(ty.value),
@ -1274,20 +1272,13 @@ 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(); let cause = ObligationCause::dummy();
match tcx let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
.infer_ctxt() infcx.at(&cause, param_env).query_normalize(ty).map_or(ty, |ty| ty.value)
.build(TypingMode::from_param_env(param_env))
.at(&cause, param_env)
.query_normalize(ty)
{
Ok(ty) => ty.value,
Err(_) => ty,
}
} }
/// Checks if the type is `core::mem::ManuallyDrop<_>` /// Checks if the type is `core::mem::ManuallyDrop<_>`