Rollup merge of #133751 - lcnr:no-trait-solving-on-type, r=compiler-errors
remove `Ty::is_copy_modulo_regions` Using these functions is likely incorrect if an `InferCtxt` is available, I moved this function to `TyCtxt` (and added it to `LateContext`) and added a note to the documentation that one should prefer `Infer::type_is_copy_modulo_regions` instead. I didn't yet move `is_sized` and `is_freeze`, though I think we should move these as well. r? `@compiler-errors` cc #132279
This commit is contained in:
commit
4c68112df1
16 changed files with 40 additions and 40 deletions
|
@ -103,7 +103,7 @@ fn allowed_union_or_unsafe_field<'tcx>(
|
|||
// Fallback case: allow `ManuallyDrop` and things that are `Copy`,
|
||||
// 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.is_copy_modulo_regions(tcx, typing_env)
|
||||
|| tcx.type_is_copy_modulo_regions(typing_env, ty)
|
||||
|| ty.references_error()
|
||||
}
|
||||
};
|
||||
|
|
|
@ -178,7 +178,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||
|
||||
// Check that the type implements Copy. The only case where this can
|
||||
// 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";
|
||||
self.tcx
|
||||
.dcx()
|
||||
|
|
|
@ -228,7 +228,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) {
|
|||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -586,7 +586,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
|
|||
return;
|
||||
}
|
||||
}
|
||||
if ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()) {
|
||||
if cx.type_is_copy_modulo_regions(ty) {
|
||||
return;
|
||||
}
|
||||
if type_implements_negative_copy_modulo_regions(cx.tcx, ty, cx.typing_env()) {
|
||||
|
|
|
@ -710,6 +710,10 @@ impl<'tcx> LateContext<'tcx> {
|
|||
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,
|
||||
/// or `None` if outside a body.
|
||||
pub fn maybe_typeck_results(&self) -> Option<&'tcx ty::TypeckResults<'tcx>> {
|
||||
|
|
|
@ -144,7 +144,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
|
|||
&& let Some(fn_name) = cx.tcx.get_diagnostic_name(def_id)
|
||||
{
|
||||
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 let_underscore_ignore_sugg = || {
|
||||
if let Some((_, node)) = cx.tcx.hir().parent_iter(expr.hir_id).nth(0)
|
||||
|
|
|
@ -242,17 +242,10 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &Path<'_>) -> Option<String> {
|
|||
}
|
||||
// Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait.
|
||||
Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => {
|
||||
if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind() {
|
||||
if let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(adt.did())
|
||||
{
|
||||
// NOTE: This path is currently unreachable as `Ty<'tcx>` is
|
||||
// defined as a type alias meaning that `impl<'tcx> Ty<'tcx>`
|
||||
// is not actually allowed.
|
||||
//
|
||||
// I(@lcnr) still kept this branch in so we don't miss this
|
||||
// if we ever change it in the future.
|
||||
return Some(format!("{}<{}>", name, args[0]));
|
||||
}
|
||||
if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind()
|
||||
&& let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(adt.did())
|
||||
{
|
||||
return Some(format!("{}<{}>", name, args[0]));
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
|
|
|
@ -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
|
||||
/// not a structure at all. Corresponds to the only possible unsized field,
|
||||
/// 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))
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// compile time (i.e., whether `T: Sized`). Lifetimes are ignored
|
||||
/// for the purposes of this check, so it can be an
|
||||
|
|
|
@ -176,7 +176,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let ty = expr.ty;
|
||||
if !ty.is_sized(tcx, this.typing_env()) {
|
||||
// !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
|
||||
// type, and that value is coming from the deref of a box.
|
||||
|
|
|
@ -780,7 +780,7 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat:
|
|||
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;
|
||||
|
||||
|
|
|
@ -609,7 +609,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
if let Operand::Copy(place) = operand {
|
||||
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}"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
// FIXME(#132279): This should be removed as it causes us to incorrectly
|
||||
// handle opaques in their defining scope.
|
||||
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);
|
||||
|
|
|
@ -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) => {
|
||||
for upvar in args.as_closure().upvar_tys() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
},
|
||||
|
@ -158,7 +158,7 @@ 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.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.
|
||||
&& (!requires_deref || arg_ty.is_freeze(cx.tcx, cx.typing_env()))
|
||||
{
|
||||
|
|
|
@ -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.typing_env())
|
||||
let by_ref = !cx.type_is_copy_modulo_regions(caller_ty)
|
||||
&& !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)) {
|
||||
|
|
|
@ -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.typing_env())
|
||||
cx.type_is_copy_modulo_regions(ty)
|
||||
}
|
||||
|
||||
/// This checks whether a given type is known to implement Debug.
|
||||
|
|
Loading…
Add table
Reference in a new issue