@@ -8,6 +8,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
88use rustc_hir as hir;
99use rustc_hir:: lang_items:: LangItem ;
1010use rustc_hir:: { is_range_literal, Node } ;
11+ use rustc_middle:: lint:: in_external_macro;
1112use rustc_middle:: ty:: adjustment:: AllowTwoPhase ;
1213use rustc_middle:: ty:: { self , AssocItem , Ty , TypeAndMut } ;
1314use rustc_span:: symbol:: sym;
@@ -412,25 +413,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
412413 checked_ty : Ty < ' tcx > ,
413414 expected : Ty < ' tcx > ,
414415 ) -> Option < ( Span , & ' static str , String , Applicability ) > {
415- let sm = self . sess ( ) . source_map ( ) ;
416+ let sess = self . sess ( ) ;
416417 let sp = expr. span ;
417- if sm . is_imported ( sp ) {
418- // Ignore if span is from within a macro #41858, #58298. We previously used the macro
419- // call span, but that breaks down when the type error comes from multiple calls down.
418+
419+ // If the span is from an external macro, there's no suggestion we can make.
420+ if in_external_macro ( sess , sp ) {
420421 return None ;
421422 }
422423
424+ let sm = sess. source_map ( ) ;
425+
423426 let replace_prefix = |s : & str , old : & str , new : & str | {
424427 s. strip_prefix ( old) . map ( |stripped| new. to_string ( ) + stripped)
425428 } ;
426429
427430 let is_struct_pat_shorthand_field =
428431 self . is_hir_id_from_struct_pattern_shorthand_field ( expr. hir_id , sp) ;
429432
430- // If the span is from a macro, then it's hard to extract the text
431- // and make a good suggestion, so don't bother.
432- let is_macro = sp. from_expansion ( ) && sp. desugaring_kind ( ) . is_none ( ) ;
433-
434433 // `ExprKind::DropTemps` is semantically irrelevant for these suggestions.
435434 let expr = expr. peel_drop_temps ( ) ;
436435
@@ -570,10 +569,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
570569 hir:: ExprKind :: AddrOf ( hir:: BorrowKind :: Ref , _, ref expr) ,
571570 _,
572571 & ty:: Ref ( _, checked, _) ,
573- ) if {
574- self . infcx . can_sub ( self . param_env , checked, & expected) . is_ok ( ) && !is_macro
575- } =>
576- {
572+ ) if self . infcx . can_sub ( self . param_env , checked, & expected) . is_ok ( ) => {
577573 // We have `&T`, check if what was expected was `T`. If so,
578574 // we may want to suggest removing a `&`.
579575 if sm. is_imported ( expr. span ) {
@@ -589,13 +585,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
589585 }
590586 return None ;
591587 }
592- if let Ok ( code) = sm. span_to_snippet ( expr. span ) {
593- return Some ( (
594- sp,
595- "consider removing the borrow" ,
596- code,
597- Applicability :: MachineApplicable ,
598- ) ) ;
588+ if sp. contains ( expr. span ) {
589+ if let Ok ( code) = sm. span_to_snippet ( expr. span ) {
590+ return Some ( (
591+ sp,
592+ "consider removing the borrow" ,
593+ code,
594+ Applicability :: MachineApplicable ,
595+ ) ) ;
596+ }
599597 }
600598 }
601599 (
@@ -643,7 +641,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
643641 }
644642 }
645643 }
646- _ if sp == expr. span && !is_macro => {
644+ _ if sp == expr. span => {
647645 if let Some ( steps) = self . deref_steps ( checked_ty, expected) {
648646 let expr = expr. peel_blocks ( ) ;
649647
0 commit comments