1
Fork 0

remove Ty::is_copy_modulo_regions

This commit is contained in:
lcnr 2024-12-02 13:57:56 +01:00
parent cfee10ce89
commit e089bead32
15 changed files with 36 additions and 29 deletions

View file

@ -103,7 +103,7 @@ fn allowed_union_or_unsafe_field<'tcx>(
// Fallback case: allow `ManuallyDrop` and things that are `Copy`, // Fallback case: allow `ManuallyDrop` and things that are `Copy`,
// also no need to report an error if the type is unresolved. // also no need to report an error if the type is unresolved.
ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop()) ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop())
|| ty.is_copy_modulo_regions(tcx, typing_env) || tcx.type_is_copy_modulo_regions(typing_env, ty)
|| ty.references_error() || ty.references_error()
} }
}; };

View file

@ -178,7 +178,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
// Check that the type implements Copy. The only case where this can // Check that the type implements Copy. The only case where this can
// possibly fail is for SIMD types which don't #[derive(Copy)]. // possibly fail is for SIMD types which don't #[derive(Copy)].
if !ty.is_copy_modulo_regions(self.tcx, self.typing_env) { if !self.tcx.type_is_copy_modulo_regions(self.typing_env, ty) {
let msg = "arguments for inline assembly must be copyable"; let msg = "arguments for inline assembly must be copyable";
self.tcx self.tcx
.dcx() .dcx()

View file

@ -228,7 +228,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) {
} }
fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool { fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
ty.is_copy_modulo_regions(self.0.tcx, self.0.typing_env()) self.0.type_is_copy_modulo_regions(ty)
} }
fn body_owner_def_id(&self) -> LocalDefId { fn body_owner_def_id(&self) -> LocalDefId {

View file

@ -586,7 +586,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
return; return;
} }
} }
if ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()) { if cx.type_is_copy_modulo_regions(ty) {
return; return;
} }
if type_implements_negative_copy_modulo_regions(cx.tcx, ty, cx.typing_env()) { if type_implements_negative_copy_modulo_regions(cx.tcx, ty, cx.typing_env()) {

View file

@ -710,6 +710,10 @@ impl<'tcx> LateContext<'tcx> {
TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env } TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env }
} }
pub fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
self.tcx.type_is_copy_modulo_regions(self.typing_env(), ty)
}
/// Gets the type-checking results for the current body, /// Gets the type-checking results for the current body,
/// or `None` if outside a body. /// or `None` if outside a body.
pub fn maybe_typeck_results(&self) -> Option<&'tcx ty::TypeckResults<'tcx>> { pub fn maybe_typeck_results(&self) -> Option<&'tcx ty::TypeckResults<'tcx>> {

View file

@ -144,7 +144,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
&& let Some(fn_name) = cx.tcx.get_diagnostic_name(def_id) && let Some(fn_name) = cx.tcx.get_diagnostic_name(def_id)
{ {
let arg_ty = cx.typeck_results().expr_ty(arg); let arg_ty = cx.typeck_results().expr_ty(arg);
let is_copy = arg_ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()); let is_copy = cx.type_is_copy_modulo_regions(arg_ty);
let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr);
let let_underscore_ignore_sugg = || { let let_underscore_ignore_sugg = || {
if let Some((_, node)) = cx.tcx.hir().parent_iter(expr.hir_id).nth(0) if let Some((_, node)) = cx.tcx.hir().parent_iter(expr.hir_id).nth(0)

View file

@ -172,6 +172,24 @@ impl<'tcx> TyCtxt<'tcx> {
} }
} }
/// Checks whether `ty: Copy` holds while ignoring region constraints.
///
/// This impacts whether values of `ty` are *moved* or *copied*
/// when referenced. This means that we may generate MIR which
/// does copies even when the type actually doesn't satisfy the
/// full requirements for the `Copy` trait (cc #29149) -- this
/// winds up being reported as an error during NLL borrow check.
///
/// This function should not be used if there is an `InferCtxt` available.
/// Use `InferCtxt::type_is_copy_modulo_regions` instead.
pub fn type_is_copy_modulo_regions(
self,
typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>,
) -> bool {
ty.is_trivially_pure_clone_copy() || self.is_copy_raw(typing_env.as_query_input(ty))
}
/// Returns the deeply last field of nested structures, or the same type if /// Returns the deeply last field of nested structures, or the same type if
/// not a structure at all. Corresponds to the only possible unsized field, /// not a structure at all. Corresponds to the only possible unsized field,
/// and its type can be used to determine unsizing strategy. /// and its type can be used to determine unsizing strategy.
@ -1174,21 +1192,6 @@ impl<'tcx> Ty<'tcx> {
.map(|(min, _)| ty::Const::from_bits(tcx, min, typing_env, self)) .map(|(min, _)| ty::Const::from_bits(tcx, min, typing_env, self))
} }
/// Checks whether values of this type `T` are *moved* or *copied*
/// when referenced -- this amounts to a check for whether `T:
/// Copy`, but note that we **don't** consider lifetimes when
/// doing this check. This means that we may generate MIR which
/// does copies even when the type actually doesn't satisfy the
/// full requirements for the `Copy` trait (cc #29149) -- this
/// winds up being reported as an error during NLL borrow check.
pub fn is_copy_modulo_regions(
self,
tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
) -> bool {
self.is_trivially_pure_clone_copy() || tcx.is_copy_raw(typing_env.as_query_input(self))
}
/// Checks whether values of this type `T` have a size known at /// Checks whether values of this type `T` have a size known at
/// compile time (i.e., whether `T: Sized`). Lifetimes are ignored /// compile time (i.e., whether `T: Sized`). Lifetimes are ignored
/// for the purposes of this check, so it can be an /// for the purposes of this check, so it can be an

View file

@ -176,7 +176,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let ty = expr.ty; let ty = expr.ty;
if !ty.is_sized(tcx, this.typing_env()) { if !ty.is_sized(tcx, this.typing_env()) {
// !sized means !copy, so this is an unsized move // !sized means !copy, so this is an unsized move
assert!(!ty.is_copy_modulo_regions(tcx, this.typing_env())); assert!(!tcx.type_is_copy_modulo_regions(this.typing_env(), ty));
// As described above, detect the case where we are passing a value of unsized // As described above, detect the case where we are passing a value of unsized
// type, and that value is coming from the deref of a box. // type, and that value is coming from the deref of a box.

View file

@ -780,7 +780,7 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat:
return; return;
}; };
let is_binding_by_move = |ty: Ty<'tcx>| !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env); let is_binding_by_move = |ty: Ty<'tcx>| !cx.tcx.type_is_copy_modulo_regions(cx.typing_env, ty);
let sess = cx.tcx.sess; let sess = cx.tcx.sess;

View file

@ -624,7 +624,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
if let Operand::Copy(place) = operand { if let Operand::Copy(place) = operand {
let ty = place.ty(&self.body.local_decls, self.tcx).ty; let ty = place.ty(&self.body.local_decls, self.tcx).ty;
if !ty.is_copy_modulo_regions(self.tcx, self.typing_env) { if !self.tcx.type_is_copy_modulo_regions(self.typing_env, ty) {
self.fail(location, format!("`Operand::Copy` with non-`Copy` type {ty}")); self.fail(location, format!("`Operand::Copy` with non-`Copy` type {ty}"));
} }
} }

View file

@ -35,7 +35,7 @@ impl<'tcx> InferCtxt<'tcx> {
// FIXME(#132279): This should be removed as it causes us to incorrectly // FIXME(#132279): This should be removed as it causes us to incorrectly
// handle opaques in their defining scope. // handle opaques in their defining scope.
if !(param_env, ty).has_infer() { if !(param_env, ty).has_infer() {
return ty.is_copy_modulo_regions(self.tcx, self.typing_env(param_env)); return self.tcx.type_is_copy_modulo_regions(self.typing_env(param_env), ty);
} }
let copy_def_id = self.tcx.require_lang_item(LangItem::Copy, None); let copy_def_id = self.tcx.require_lang_item(LangItem::Copy, None);

View file

@ -202,7 +202,7 @@ where
} }
} }
_ if component.is_copy_modulo_regions(tcx, self.typing_env) => {} _ if tcx.type_is_copy_modulo_regions(self.typing_env, component) => {}
ty::Closure(_, args) => { ty::Closure(_, args) => {
for upvar in args.as_closure().upvar_tys() { for upvar in args.as_closure().upvar_tys() {

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

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 mut applicability = Applicability::MachineApplicable;
let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability); let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability);
let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()) let by_ref = !cx.type_is_copy_modulo_regions(caller_ty)
&& !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..)); && !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..));
let sugg = if let Some(else_inner) = r#else { let sugg = if let Some(else_inner) = r#else {
if eq_expr_value(cx, caller, peel_blocks(else_inner)) { if eq_expr_value(cx, caller, peel_blocks(else_inner)) {

View file

@ -38,7 +38,7 @@ pub use type_certainty::expr_type_is_certain;
/// Checks if the given type implements copy. /// Checks if the given type implements copy.
pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()) cx.type_is_copy_modulo_regions(ty)
} }
/// This checks whether a given type is known to implement Debug. /// This checks whether a given type is known to implement Debug.