use TypingEnv
when no infcx
is available
the behavior of the type system not only depends on the current assumptions, but also the currentnphase of the compiler. This is mostly necessary as we need to decide whether and how to reveal opaque types. We track this via the `TypingMode`.
This commit is contained in:
parent
1ceaa90413
commit
bb93c23c08
33 changed files with 83 additions and 79 deletions
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
})
|
||||
|
|
|
@ -17,7 +17,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};
|
||||
|
@ -755,7 +755,8 @@ impl TyCoercionStability {
|
|||
DefinedTy::Hir(ty) => Self::for_hir_ty(ty),
|
||||
DefinedTy::Mir(ty) => Self::for_mir_ty(
|
||||
cx.tcx,
|
||||
ty.param_env,
|
||||
// FIXME(#132279): convert `DefinedTy` to use `TypingEnv` instead.
|
||||
ty::TypingEnv::from_param_env(ty.param_env),
|
||||
cx.tcx.instantiate_bound_regions_with_erased(ty.value),
|
||||
for_return,
|
||||
),
|
||||
|
@ -823,12 +824,12 @@ 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>, typing_env: ty::TypingEnv<'tcx>, 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);
|
||||
ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);
|
||||
loop {
|
||||
break match *ty.kind() {
|
||||
ty::Ref(_, ref_ty, _) => {
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -4,7 +4,7 @@ use rustc_errors::Applicability;
|
|||
use rustc_hir::{Item, ItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::{self, ParamEnv};
|
||||
use rustc_middle::ty;
|
||||
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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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()))
|
||||
})
|
||||
};
|
||||
|
|
|
@ -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,7 @@ 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 +204,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 +222,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 +240,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))
|
||||
|
|
|
@ -203,10 +203,10 @@ 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 +237,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 {
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -278,23 +278,23 @@ impl<'tcx> NonCopyConst<'tcx> {
|
|||
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.param_env, cid, span)
|
||||
},
|
||||
Ok(None) => Err(ErrorHandled::TooGeneric(span)),
|
||||
Err(err) => Err(ErrorHandled::Reported(err.into(), span)),
|
||||
|
@ -321,7 +321,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 +361,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 +376,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 +386,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)
|
||||
|
|
|
@ -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))),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -58,7 +58,7 @@ fn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item:
|
|||
&& 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())
|
||||
.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)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
@ -813,7 +813,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
|
||||
|
|
|
@ -1631,7 +1631,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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
@ -408,15 +408,17 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
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 +436,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)
|
||||
}
|
||||
|
|
|
@ -467,7 +467,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 +575,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_reveal_all_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 +726,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 +1112,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 +1133,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 +1141,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
|
||||
|
@ -1300,7 +1301,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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue