@@ -10,6 +10,7 @@ use rustc_middle::ty::{self, Ty};
1010use rustc_mir_dataflow:: move_paths:: { LookupResult , MovePathIndex } ;
1111use rustc_span:: { BytePos , ExpnKind , MacroKind , Span } ;
1212use rustc_trait_selection:: error_reporting:: traits:: FindExprBySpan ;
13+ use rustc_trait_selection:: infer:: InferCtxtExt ;
1314use tracing:: debug;
1415
1516use crate :: MirBorrowckCtxt ;
@@ -267,6 +268,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
267268 kind,
268269 self . is_upvar_field_projection( original_path. as_ref( ) )
269270 ) ;
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 . dcx ( ) . span_delayed_bug (
275+ span,
276+ "Type may implement copy, but there is no other error." ,
277+ ) ;
278+ return ;
279+ }
270280 (
271281 match kind {
272282 & IllegalMoveOriginKind :: BorrowedContent { target_place } => self
@@ -291,6 +301,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
291301 self . buffer_error ( err) ;
292302 }
293303
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+
294311 fn report_cannot_move_from_static ( & mut self , place : Place < ' tcx > , span : Span ) -> Diag < ' infcx > {
295312 let description = if place. projection . len ( ) == 1 {
296313 format ! ( "static item {}" , self . describe_any_place( place. as_ref( ) ) )
0 commit comments