@@ -3070,7 +3070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30703070 "ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, base_ty={:?}" ,
30713071 ident, base, expr, base_ty
30723072 ) ;
3073- let mut err = self . no_such_field_err ( ident, base_ty, base . hir_id ) ;
3073+ let mut err = self . no_such_field_err ( ident, base_ty, expr ) ;
30743074
30753075 match * base_ty. peel_refs ( ) . kind ( ) {
30763076 ty:: Array ( _, len) => {
@@ -3283,32 +3283,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
32833283 ) ;
32843284 }
32853285
3286- fn no_such_field_err ( & self , field : Ident , expr_t : Ty < ' tcx > , id : HirId ) -> Diag < ' _ > {
3286+ fn no_such_field_err (
3287+ & self ,
3288+ field : Ident ,
3289+ base_ty : Ty < ' tcx > ,
3290+ expr : & hir:: Expr < ' tcx > ,
3291+ ) -> Diag < ' _ > {
32873292 let span = field. span ;
3288- debug ! ( "no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})" , span, field, expr_t ) ;
3293+ debug ! ( "no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})" , span, field, base_ty ) ;
32893294
32903295 let mut err = type_error_struct ! (
32913296 self . dcx( ) ,
32923297 span,
3293- expr_t ,
3298+ base_ty ,
32943299 E0609 ,
3295- "no field `{field}` on type `{expr_t }`" ,
3300+ "no field `{field}` on type `{base_ty }`" ,
32963301 ) ;
3302+ if let Some ( within_macro_span) = span. within_macro ( expr. span , self . tcx . sess . source_map ( ) ) {
3303+ err. span_note ( within_macro_span, "within this macro" ) ;
3304+ }
32973305
32983306 // try to add a suggestion in case the field is a nested field of a field of the Adt
3299- let mod_id = self . tcx . parent_module ( id ) . to_def_id ( ) ;
3300- let ( ty, unwrap) = if let ty:: Adt ( def, args) = expr_t . kind ( )
3307+ let mod_id = self . tcx . parent_module ( expr . hir_id ) . to_def_id ( ) ;
3308+ let ( ty, unwrap) = if let ty:: Adt ( def, args) = base_ty . kind ( )
33013309 && ( self . tcx . is_diagnostic_item ( sym:: Result , def. did ( ) )
33023310 || self . tcx . is_diagnostic_item ( sym:: Option , def. did ( ) ) )
33033311 && let Some ( arg) = args. get ( 0 )
33043312 && let Some ( ty) = arg. as_type ( )
33053313 {
33063314 ( ty, "unwrap()." )
33073315 } else {
3308- ( expr_t , "" )
3316+ ( base_ty , "" )
33093317 } ;
33103318 for ( found_fields, args) in
3311- self . get_field_candidates_considering_privacy_for_diag ( span, ty, mod_id, id )
3319+ self . get_field_candidates_considering_privacy_for_diag ( span, ty, mod_id, expr . hir_id )
33123320 {
33133321 let field_names = found_fields. iter ( ) . map ( |field| field. name ) . collect :: < Vec < _ > > ( ) ;
33143322 let mut candidate_fields: Vec < _ > = found_fields
@@ -3321,7 +3329,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
33213329 args,
33223330 vec ! [ ] ,
33233331 mod_id,
3324- id ,
3332+ expr . hir_id ,
33253333 )
33263334 } )
33273335 . map ( |mut field_path| {
@@ -3332,7 +3340,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
33323340 candidate_fields. sort ( ) ;
33333341
33343342 let len = candidate_fields. len ( ) ;
3335- if len > 0 {
3343+ // Don't suggest `.field` if the base expr is from a different
3344+ // syntax context than the field.
3345+ if len > 0 && expr. span . eq_ctxt ( field. span ) {
33363346 err. span_suggestions (
33373347 field. span . shrink_to_lo ( ) ,
33383348 format ! (
@@ -3968,7 +3978,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
39683978 _ => ( ) ,
39693979 } ;
39703980
3971- self . no_such_field_err ( field, container, expr. hir_id ) . emit ( ) ;
3981+ self . no_such_field_err ( field, container, expr) . emit ( ) ;
39723982
39733983 break ;
39743984 }
0 commit comments