@@ -1394,30 +1394,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1394
1394
} else if self . method_exists ( field, expr_t, expr. hir_id , true ) {
1395
1395
self . ban_take_value_of_method ( expr, expr_t, field) ;
1396
1396
} else if !expr_t. is_primitive_ty ( ) {
1397
- let mut err = self . no_such_field_err ( field. span , field, expr_t) ;
1398
-
1399
- match expr_t. kind {
1400
- ty:: Adt ( def, _) if !def. is_enum ( ) => {
1401
- self . suggest_fields_on_recordish ( & mut err, def, field) ;
1402
- }
1403
- ty:: Array ( _, len) => {
1404
- self . maybe_suggest_array_indexing ( & mut err, expr, base, field, len) ;
1405
- }
1406
- ty:: RawPtr ( ..) => {
1407
- self . suggest_first_deref_field ( & mut err, expr, base, field) ;
1408
- }
1409
- _ => { }
1410
- }
1411
-
1412
- if field. name == kw:: Await {
1413
- // We know by construction that `<expr>.await` is either on Rust 2015
1414
- // or results in `ExprKind::Await`. Suggest switching the edition to 2018.
1415
- err. note ( "to `.await` a `Future`, switch to Rust 2018" ) ;
1416
- err. help ( "set `edition = \" 2018\" ` in `Cargo.toml`" ) ;
1417
- err. note ( "for more on editions, read https://doc.rust-lang.org/edition-guide" ) ;
1418
- }
1419
-
1420
- err. emit ( ) ;
1397
+ self . ban_nonexisting_field ( field, base, expr, expr_t) ;
1421
1398
} else {
1422
1399
type_error_struct ! (
1423
1400
self . tcx( ) . sess,
@@ -1433,6 +1410,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1433
1410
self . tcx ( ) . types . err
1434
1411
}
1435
1412
1413
+ fn ban_nonexisting_field (
1414
+ & self ,
1415
+ field : ast:: Ident ,
1416
+ base : & ' tcx hir:: Expr ,
1417
+ expr : & ' tcx hir:: Expr ,
1418
+ expr_t : Ty < ' tcx > ,
1419
+ ) {
1420
+ let mut err = self . no_such_field_err ( field. span , field, expr_t) ;
1421
+
1422
+ match expr_t. peel_refs ( ) . kind {
1423
+ ty:: Array ( _, len) => {
1424
+ self . maybe_suggest_array_indexing ( & mut err, expr, base, field, len) ;
1425
+ }
1426
+ ty:: RawPtr ( ..) => {
1427
+ self . suggest_first_deref_field ( & mut err, expr, base, field) ;
1428
+ }
1429
+ ty:: Adt ( def, _) if !def. is_enum ( ) => {
1430
+ self . suggest_fields_on_recordish ( & mut err, def, field) ;
1431
+ }
1432
+ ty:: Param ( param_ty) => {
1433
+ self . point_at_param_definition ( & mut err, param_ty) ;
1434
+ }
1435
+ _ => { }
1436
+ }
1437
+
1438
+ if field. name == kw:: Await {
1439
+ // We know by construction that `<expr>.await` is either on Rust 2015
1440
+ // or results in `ExprKind::Await`. Suggest switching the edition to 2018.
1441
+ err. note ( "to `.await` a `Future`, switch to Rust 2018" ) ;
1442
+ err. help ( "set `edition = \" 2018\" ` in `Cargo.toml`" ) ;
1443
+ err. note ( "for more on editions, read https://doc.rust-lang.org/edition-guide" ) ;
1444
+ }
1445
+
1446
+ err. emit ( ) ;
1447
+ }
1448
+
1436
1449
fn ban_private_field_access (
1437
1450
& self ,
1438
1451
expr : & hir:: Expr ,
@@ -1495,6 +1508,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1495
1508
err. emit ( ) ;
1496
1509
}
1497
1510
1511
+ fn point_at_param_definition ( & self , err : & mut DiagnosticBuilder < ' _ > , param : ty:: ParamTy ) {
1512
+ let generics = self . tcx . generics_of ( self . body_id . owner_def_id ( ) ) ;
1513
+ let generic_param = generics. type_param ( & param, self . tcx ) ;
1514
+ if let ty:: GenericParamDefKind :: Type { synthetic : Some ( ..) , ..} = generic_param. kind {
1515
+ return ;
1516
+ }
1517
+ let param_def_id = generic_param. def_id ;
1518
+ let param_hir_id = match self . tcx . hir ( ) . as_local_hir_id ( param_def_id) {
1519
+ Some ( x) => x,
1520
+ None => return ,
1521
+ } ;
1522
+ let param_span = self . tcx . hir ( ) . span ( param_hir_id) ;
1523
+ let param_name = self . tcx . hir ( ) . ty_param_name ( param_hir_id) ;
1524
+
1525
+ err. span_label ( param_span, & format ! ( "type parameter '{}' declared here" , param_name) ) ;
1526
+ }
1527
+
1498
1528
fn suggest_fields_on_recordish (
1499
1529
& self ,
1500
1530
err : & mut DiagnosticBuilder < ' _ > ,
0 commit comments