Skip to content

Commit 4c68112

Browse files
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
2 parents 7c92266 + e089bea commit 4c68112

File tree

16 files changed

+40
-40
lines changed

16 files changed

+40
-40
lines changed

compiler/rustc_hir_analysis/src/check/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ fn allowed_union_or_unsafe_field<'tcx>(
103103
// Fallback case: allow `ManuallyDrop` and things that are `Copy`,
104104
// also no need to report an error if the type is unresolved.
105105
ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop())
106-
|| ty.is_copy_modulo_regions(tcx, typing_env)
106+
|| tcx.type_is_copy_modulo_regions(typing_env, ty)
107107
|| ty.references_error()
108108
}
109109
};

compiler/rustc_hir_analysis/src/check/intrinsicck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
178178

179179
// Check that the type implements Copy. The only case where this can
180180
// possibly fail is for SIMD types which don't #[derive(Copy)].
181-
if !ty.is_copy_modulo_regions(self.tcx, self.typing_env) {
181+
if !self.tcx.type_is_copy_modulo_regions(self.typing_env, ty) {
182182
let msg = "arguments for inline assembly must be copyable";
183183
self.tcx
184184
.dcx()

compiler/rustc_hir_typeck/src/expr_use_visitor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) {
228228
}
229229

230230
fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
231-
ty.is_copy_modulo_regions(self.0.tcx, self.0.typing_env())
231+
self.0.type_is_copy_modulo_regions(ty)
232232
}
233233

234234
fn body_owner_def_id(&self) -> LocalDefId {

compiler/rustc_lint/src/builtin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
586586
return;
587587
}
588588
}
589-
if ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()) {
589+
if cx.type_is_copy_modulo_regions(ty) {
590590
return;
591591
}
592592
if type_implements_negative_copy_modulo_regions(cx.tcx, ty, cx.typing_env()) {

compiler/rustc_lint/src/context.rs

+4
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,10 @@ impl<'tcx> LateContext<'tcx> {
710710
TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env }
711711
}
712712

713+
pub fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
714+
self.tcx.type_is_copy_modulo_regions(self.typing_env(), ty)
715+
}
716+
713717
/// Gets the type-checking results for the current body,
714718
/// or `None` if outside a body.
715719
pub fn maybe_typeck_results(&self) -> Option<&'tcx ty::TypeckResults<'tcx>> {

compiler/rustc_lint/src/drop_forget_useless.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
144144
&& let Some(fn_name) = cx.tcx.get_diagnostic_name(def_id)
145145
{
146146
let arg_ty = cx.typeck_results().expr_ty(arg);
147-
let is_copy = arg_ty.is_copy_modulo_regions(cx.tcx, cx.typing_env());
147+
let is_copy = cx.type_is_copy_modulo_regions(arg_ty);
148148
let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr);
149149
let let_underscore_ignore_sugg = || {
150150
if let Some((_, node)) = cx.tcx.hir().parent_iter(expr.hir_id).nth(0)

compiler/rustc_lint/src/internal.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -242,17 +242,10 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &Path<'_>) -> Option<String> {
242242
}
243243
// Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait.
244244
Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => {
245-
if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind() {
246-
if let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(adt.did())
247-
{
248-
// NOTE: This path is currently unreachable as `Ty<'tcx>` is
249-
// defined as a type alias meaning that `impl<'tcx> Ty<'tcx>`
250-
// is not actually allowed.
251-
//
252-
// I(@lcnr) still kept this branch in so we don't miss this
253-
// if we ever change it in the future.
254-
return Some(format!("{}<{}>", name, args[0]));
255-
}
245+
if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind()
246+
&& let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(adt.did())
247+
{
248+
return Some(format!("{}<{}>", name, args[0]));
256249
}
257250
}
258251
_ => (),

compiler/rustc_middle/src/ty/util.rs

+18-15
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,24 @@ impl<'tcx> TyCtxt<'tcx> {
172172
}
173173
}
174174

175+
/// Checks whether `ty: Copy` holds while ignoring region constraints.
176+
///
177+
/// This impacts whether values of `ty` are *moved* or *copied*
178+
/// when referenced. This means that we may generate MIR which
179+
/// does copies even when the type actually doesn't satisfy the
180+
/// full requirements for the `Copy` trait (cc #29149) -- this
181+
/// winds up being reported as an error during NLL borrow check.
182+
///
183+
/// This function should not be used if there is an `InferCtxt` available.
184+
/// Use `InferCtxt::type_is_copy_modulo_regions` instead.
185+
pub fn type_is_copy_modulo_regions(
186+
self,
187+
typing_env: ty::TypingEnv<'tcx>,
188+
ty: Ty<'tcx>,
189+
) -> bool {
190+
ty.is_trivially_pure_clone_copy() || self.is_copy_raw(typing_env.as_query_input(ty))
191+
}
192+
175193
/// Returns the deeply last field of nested structures, or the same type if
176194
/// not a structure at all. Corresponds to the only possible unsized field,
177195
/// and its type can be used to determine unsizing strategy.
@@ -1174,21 +1192,6 @@ impl<'tcx> Ty<'tcx> {
11741192
.map(|(min, _)| ty::Const::from_bits(tcx, min, typing_env, self))
11751193
}
11761194

1177-
/// Checks whether values of this type `T` are *moved* or *copied*
1178-
/// when referenced -- this amounts to a check for whether `T:
1179-
/// Copy`, but note that we **don't** consider lifetimes when
1180-
/// doing this check. This means that we may generate MIR which
1181-
/// does copies even when the type actually doesn't satisfy the
1182-
/// full requirements for the `Copy` trait (cc #29149) -- this
1183-
/// winds up being reported as an error during NLL borrow check.
1184-
pub fn is_copy_modulo_regions(
1185-
self,
1186-
tcx: TyCtxt<'tcx>,
1187-
typing_env: ty::TypingEnv<'tcx>,
1188-
) -> bool {
1189-
self.is_trivially_pure_clone_copy() || tcx.is_copy_raw(typing_env.as_query_input(self))
1190-
}
1191-
11921195
/// Checks whether values of this type `T` have a size known at
11931196
/// compile time (i.e., whether `T: Sized`). Lifetimes are ignored
11941197
/// for the purposes of this check, so it can be an

compiler/rustc_mir_build/src/build/expr/as_operand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
176176
let ty = expr.ty;
177177
if !ty.is_sized(tcx, this.typing_env()) {
178178
// !sized means !copy, so this is an unsized move
179-
assert!(!ty.is_copy_modulo_regions(tcx, this.typing_env()));
179+
assert!(!tcx.type_is_copy_modulo_regions(this.typing_env(), ty));
180180

181181
// As described above, detect the case where we are passing a value of unsized
182182
// type, and that value is coming from the deref of a box.

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat:
780780
return;
781781
};
782782

783-
let is_binding_by_move = |ty: Ty<'tcx>| !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env);
783+
let is_binding_by_move = |ty: Ty<'tcx>| !cx.tcx.type_is_copy_modulo_regions(cx.typing_env, ty);
784784

785785
let sess = cx.tcx.sess;
786786

compiler/rustc_mir_transform/src/validate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
609609
if let Operand::Copy(place) = operand {
610610
let ty = place.ty(&self.body.local_decls, self.tcx).ty;
611611

612-
if !ty.is_copy_modulo_regions(self.tcx, self.typing_env) {
612+
if !self.tcx.type_is_copy_modulo_regions(self.typing_env, ty) {
613613
self.fail(location, format!("`Operand::Copy` with non-`Copy` type {ty}"));
614614
}
615615
}

compiler/rustc_trait_selection/src/infer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl<'tcx> InferCtxt<'tcx> {
3535
// FIXME(#132279): This should be removed as it causes us to incorrectly
3636
// handle opaques in their defining scope.
3737
if !(param_env, ty).has_infer() {
38-
return ty.is_copy_modulo_regions(self.tcx, self.typing_env(param_env));
38+
return self.tcx.type_is_copy_modulo_regions(self.typing_env(param_env), ty);
3939
}
4040

4141
let copy_def_id = self.tcx.require_lang_item(LangItem::Copy, None);

compiler/rustc_ty_utils/src/needs_drop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ where
202202
}
203203
}
204204

205-
_ if component.is_copy_modulo_regions(tcx, self.typing_env) => {}
205+
_ if tcx.type_is_copy_modulo_regions(self.typing_env, component) => {}
206206

207207
ty::Closure(_, args) => {
208208
for upvar in args.as_closure().upvar_tys() {

src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
148148
_ => {},
149149
}
150150
}
151-
requires_copy |= !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env());
151+
requires_copy |= !cx.type_is_copy_modulo_regions(ty);
152152
break;
153153
}
154154
},
@@ -158,7 +158,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
158158
}
159159

160160
if can_lint
161-
&& (!requires_copy || arg_ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()))
161+
&& (!requires_copy || cx.type_is_copy_modulo_regions(arg_ty))
162162
// This case could be handled, but a fair bit of care would need to be taken.
163163
&& (!requires_deref || arg_ty.is_freeze(cx.tcx, cx.typing_env()))
164164
{

src/tools/clippy/clippy_lints/src/question_mark.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Ex
251251
{
252252
let mut applicability = Applicability::MachineApplicable;
253253
let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability);
254-
let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx, cx.typing_env())
254+
let by_ref = !cx.type_is_copy_modulo_regions(caller_ty)
255255
&& !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..));
256256
let sugg = if let Some(else_inner) = r#else {
257257
if eq_expr_value(cx, caller, peel_blocks(else_inner)) {

src/tools/clippy/clippy_utils/src/ty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub use type_certainty::expr_type_is_certain;
3838

3939
/// Checks if the given type implements copy.
4040
pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
41-
ty.is_copy_modulo_regions(cx.tcx, cx.typing_env())
41+
cx.type_is_copy_modulo_regions(ty)
4242
}
4343

4444
/// This checks whether a given type is known to implement Debug.

0 commit comments

Comments
 (0)