@@ -10,6 +10,7 @@ use rustc_middle::ty::{self, Ty};
10
10
use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex};
11
11
use rustc_span::{BytePos, ExpnKind, MacroKind, Span};
12
12
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
13
+ use rustc_trait_selection::infer::InferCtxtExt;
13
14
use tracing::debug;
14
15
15
16
use crate::MirBorrowckCtxt;
@@ -267,6 +268,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
267
268
kind,
268
269
self.is_upvar_field_projection(original_path.as_ref())
269
270
);
271
+ if self.has_ambiguous_copy(original_path.ty(self.body, self.infcx.tcx).ty) {
272
+ // If the type may implement Copy, skip the error.
273
+ // It's an error with the Copy implementation (e.g. duplicate Copy) rather than borrow check
274
+ self.span_delayed_bug(
275
+ span,
276
+ "Type may implement copy, but there is no other error.",
277
+ );
278
+ return;
279
+ }
270
280
(
271
281
match kind {
272
282
&IllegalMoveOriginKind::BorrowedContent { target_place } => self
@@ -291,6 +301,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
291
301
self.buffer_error(err);
292
302
}
293
303
304
+ fn has_ambiguous_copy(&mut self, ty: Ty<'tcx>) -> bool {
305
+ let Some(copy_trait_def) = self.infcx.tcx.lang_items().copy_trait() else { return false };
306
+ // This is only going to be ambiguous if there are incoherent impls, because otherwise
307
+ // ambiguity should never happen in MIR.
308
+ self.infcx.type_implements_trait(copy_trait_def, [ty], self.param_env).may_apply()
309
+ }
310
+
294
311
fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'infcx> {
295
312
let description = if place.projection.len() == 1 {
296
313
format!("static item {}", self.describe_any_place(place.as_ref()))
0 commit comments