@@ -3069,7 +3069,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3069
3069
"ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, base_ty={:?}" ,
3070
3070
ident, base, expr, base_ty
3071
3071
) ;
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 ) ;
3073
3073
3074
3074
match * base_ty. peel_refs ( ) . kind ( ) {
3075
3075
ty:: Array ( _, len) => {
@@ -3282,29 +3282,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3282
3282
) ;
3283
3283
}
3284
3284
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 < ' _ > {
3286
3291
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 ) ;
3288
3293
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 ( ) {
3291
3296
err. downgrade_to_delayed_bug ( ) ;
3292
3297
}
3293
3298
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
+
3294
3303
// 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 ( )
3297
3306
&& ( self . tcx . is_diagnostic_item ( sym:: Result , def. did ( ) )
3298
3307
|| self . tcx . is_diagnostic_item ( sym:: Option , def. did ( ) ) )
3299
3308
&& let Some ( arg) = args. get ( 0 )
3300
3309
&& let Some ( ty) = arg. as_type ( )
3301
3310
{
3302
3311
( ty, "unwrap()." )
3303
3312
} else {
3304
- ( expr_t , "" )
3313
+ ( base_ty , "" )
3305
3314
} ;
3306
3315
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 )
3308
3317
{
3309
3318
let field_names = found_fields. iter ( ) . map ( |field| field. name ) . collect :: < Vec < _ > > ( ) ;
3310
3319
let mut candidate_fields: Vec < _ > = found_fields
@@ -3317,7 +3326,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3317
3326
args,
3318
3327
vec ! [ ] ,
3319
3328
mod_id,
3320
- id ,
3329
+ expr . hir_id ,
3321
3330
)
3322
3331
} )
3323
3332
. map ( |mut field_path| {
@@ -3328,7 +3337,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3328
3337
candidate_fields. sort ( ) ;
3329
3338
3330
3339
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 ) {
3332
3343
err. span_suggestions (
3333
3344
field. span . shrink_to_lo ( ) ,
3334
3345
format ! (
@@ -3963,7 +3974,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3963
3974
_ => ( ) ,
3964
3975
} ;
3965
3976
3966
- self . no_such_field_err ( field, container, expr. hir_id ) . emit ( ) ;
3977
+ self . no_such_field_err ( field, container, expr) . emit ( ) ;
3967
3978
3968
3979
break ;
3969
3980
}
0 commit comments