@@ -3069,7 +3069,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30693069 "ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, base_ty={:?}" ,
30703070 ident, base, expr, base_ty
30713071 ) ;
3072- let mut err = self . no_such_field_err ( ident, base_ty, base . hir_id ) ;
3072+ let mut err = self . no_such_field_err ( ident, base_ty, expr ) ;
30733073
30743074 match * base_ty. peel_refs ( ) . kind ( ) {
30753075 ty:: Array ( _, len) => {
@@ -3282,29 +3282,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
32823282 ) ;
32833283 }
32843284
3285- fn no_such_field_err ( & self , field : Ident , expr_t : Ty < ' tcx > , id : HirId ) -> Diag < ' _ > {
3285+ fn no_such_field_err (
3286+ & self ,
3287+ field : Ident ,
3288+ base_ty : Ty < ' tcx > ,
3289+ expr : & hir:: Expr < ' tcx > ,
3290+ ) -> Diag < ' _ > {
32863291 let span = field. span ;
3287- debug ! ( "no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})" , span, field, expr_t ) ;
3292+ debug ! ( "no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})" , span, field, base_ty ) ;
32883293
3289- let mut err = self . dcx ( ) . create_err ( NoFieldOnType { span, ty : expr_t , field } ) ;
3290- if expr_t . references_error ( ) {
3294+ let mut err = self . dcx ( ) . create_err ( NoFieldOnType { span, ty : base_ty , field } ) ;
3295+ if base_ty . references_error ( ) {
32913296 err. downgrade_to_delayed_bug ( ) ;
32923297 }
32933298
3299+ if let Some ( within_macro_span) = span. within_macro ( expr. span , self . tcx . sess . source_map ( ) ) {
3300+ err. span_label ( within_macro_span, "due to this macro variable" ) ;
3301+ }
3302+
32943303 // try to add a suggestion in case the field is a nested field of a field of the Adt
3295- let mod_id = self . tcx . parent_module ( id ) . to_def_id ( ) ;
3296- let ( ty, unwrap) = if let ty:: Adt ( def, args) = expr_t . kind ( )
3304+ let mod_id = self . tcx . parent_module ( expr . hir_id ) . to_def_id ( ) ;
3305+ let ( ty, unwrap) = if let ty:: Adt ( def, args) = base_ty . kind ( )
32973306 && ( self . tcx . is_diagnostic_item ( sym:: Result , def. did ( ) )
32983307 || self . tcx . is_diagnostic_item ( sym:: Option , def. did ( ) ) )
32993308 && let Some ( arg) = args. get ( 0 )
33003309 && let Some ( ty) = arg. as_type ( )
33013310 {
33023311 ( ty, "unwrap()." )
33033312 } else {
3304- ( expr_t , "" )
3313+ ( base_ty , "" )
33053314 } ;
33063315 for ( found_fields, args) in
3307- self . get_field_candidates_considering_privacy_for_diag ( span, ty, mod_id, id )
3316+ self . get_field_candidates_considering_privacy_for_diag ( span, ty, mod_id, expr . hir_id )
33083317 {
33093318 let field_names = found_fields. iter ( ) . map ( |field| field. name ) . collect :: < Vec < _ > > ( ) ;
33103319 let mut candidate_fields: Vec < _ > = found_fields
@@ -3317,7 +3326,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
33173326 args,
33183327 vec ! [ ] ,
33193328 mod_id,
3320- id ,
3329+ expr . hir_id ,
33213330 )
33223331 } )
33233332 . map ( |mut field_path| {
@@ -3328,7 +3337,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
33283337 candidate_fields. sort ( ) ;
33293338
33303339 let len = candidate_fields. len ( ) ;
3331- if len > 0 {
3340+ // Don't suggest `.field` if the base expr is from a different
3341+ // syntax context than the field.
3342+ if len > 0 && expr. span . eq_ctxt ( field. span ) {
33323343 err. span_suggestions (
33333344 field. span . shrink_to_lo ( ) ,
33343345 format ! (
@@ -3963,7 +3974,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
39633974 _ => ( ) ,
39643975 } ;
39653976
3966- self . no_such_field_err ( field, container, expr. hir_id ) . emit ( ) ;
3977+ self . no_such_field_err ( field, container, expr) . emit ( ) ;
39673978
39683979 break ;
39693980 }
0 commit comments