@@ -38,8 +38,8 @@ use rustc_middle::middle::stability::AllowUnstable;
38
38
use rustc_middle:: mir:: interpret:: LitToConstInput ;
39
39
use rustc_middle:: ty:: print:: PrintPolyTraitRefExt as _;
40
40
use rustc_middle:: ty:: {
41
- self , AssocTag , Const , GenericArgKind , GenericArgsRef , GenericParamDefKind , ParamEnv , Ty ,
42
- TyCtxt , TypeVisitableExt , TypingMode , Upcast , fold_regions,
41
+ self , Const , GenericArgKind , GenericArgsRef , GenericParamDefKind , ParamEnv , Ty , TyCtxt ,
42
+ TypeVisitableExt , TypingMode , Upcast , fold_regions,
43
43
} ;
44
44
use rustc_middle:: { bug, span_bug} ;
45
45
use rustc_session:: lint:: builtin:: AMBIGUOUS_ASSOCIATED_ITEMS ;
@@ -937,7 +937,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
937
937
fn probe_trait_that_defines_assoc_item (
938
938
& self ,
939
939
trait_def_id : DefId ,
940
- assoc_tag : AssocTag ,
940
+ assoc_tag : ty :: AssocTag ,
941
941
assoc_ident : Ident ,
942
942
) -> bool {
943
943
self . tcx ( )
@@ -980,7 +980,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
980
980
& self ,
981
981
ty_param_def_id : LocalDefId ,
982
982
ty_param_span : Span ,
983
- assoc_tag : AssocTag ,
983
+ assoc_tag : ty :: AssocTag ,
984
984
assoc_ident : Ident ,
985
985
span : Span ,
986
986
) -> Result < ty:: PolyTraitRef < ' tcx > , ErrorGuaranteed > {
@@ -1015,7 +1015,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1015
1015
& self ,
1016
1016
all_candidates : impl Fn ( ) -> I ,
1017
1017
qself : AssocItemQSelf ,
1018
- assoc_tag : AssocTag ,
1018
+ assoc_tag : ty :: AssocTag ,
1019
1019
assoc_ident : Ident ,
1020
1020
span : Span ,
1021
1021
constraint : Option < & hir:: AssocItemConstraint < ' tcx > > ,
@@ -1238,7 +1238,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1238
1238
) -> Result < TypeRelativePath < ' tcx > , ErrorGuaranteed > {
1239
1239
debug ! ( %self_ty, ?segment. ident) ;
1240
1240
let tcx = self . tcx ( ) ;
1241
- let ident = segment. ident ;
1242
1241
1243
1242
// Check if we have an enum variant or an inherent associated type.
1244
1243
let mut variant_def_id = None ;
@@ -1247,7 +1246,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1247
1246
let variant_def = adt_def
1248
1247
. variants ( )
1249
1248
. iter ( )
1250
- . find ( |vd| tcx. hygienic_eq ( ident, vd. ident ( tcx) , adt_def. did ( ) ) ) ;
1249
+ . find ( |vd| tcx. hygienic_eq ( segment . ident , vd. ident ( tcx) , adt_def. did ( ) ) ) ;
1251
1250
if let Some ( variant_def) = variant_def {
1252
1251
if let PermitVariants :: Yes = mode. permit_variants ( ) {
1253
1252
tcx. check_stability ( variant_def. def_id , Some ( qpath_hir_id) , span, None ) ;
@@ -1282,13 +1281,70 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1282
1281
}
1283
1282
}
1284
1283
1284
+ let ( item_def_id, bound) = self . resolve_type_relative_path (
1285
+ self_ty,
1286
+ hir_self_ty,
1287
+ mode. assoc_tag ( ) ,
1288
+ segment,
1289
+ qpath_hir_id,
1290
+ span,
1291
+ variant_def_id,
1292
+ ) ?;
1293
+
1294
+ let ( item_def_id, args) = self . lower_assoc_item_path ( span, item_def_id, segment, bound) ?;
1295
+
1296
+ if let Some ( variant_def_id) = variant_def_id {
1297
+ tcx. node_span_lint ( AMBIGUOUS_ASSOCIATED_ITEMS , qpath_hir_id, span, |lint| {
1298
+ lint. primary_message ( "ambiguous associated item" ) ;
1299
+ let mut could_refer_to = |kind : DefKind , def_id, also| {
1300
+ let note_msg = format ! (
1301
+ "`{}` could{} refer to the {} defined here" ,
1302
+ segment. ident,
1303
+ also,
1304
+ tcx. def_kind_descr( kind, def_id)
1305
+ ) ;
1306
+ lint. span_note ( tcx. def_span ( def_id) , note_msg) ;
1307
+ } ;
1308
+
1309
+ could_refer_to ( DefKind :: Variant , variant_def_id, "" ) ;
1310
+ could_refer_to ( mode. def_kind ( ) , item_def_id, " also" ) ;
1311
+
1312
+ lint. span_suggestion (
1313
+ span,
1314
+ "use fully-qualified syntax" ,
1315
+ format ! (
1316
+ "<{} as {}>::{}" ,
1317
+ self_ty,
1318
+ tcx. item_name( bound. def_id( ) ) ,
1319
+ segment. ident
1320
+ ) ,
1321
+ Applicability :: MachineApplicable ,
1322
+ ) ;
1323
+ } ) ;
1324
+ }
1325
+
1326
+ Ok ( TypeRelativePath :: AssocItem ( item_def_id, args) )
1327
+ }
1328
+
1329
+ /// Resolve a [type-relative](hir::QPath::TypeRelative) (and type-level) path.
1330
+ fn resolve_type_relative_path (
1331
+ & self ,
1332
+ self_ty : Ty < ' tcx > ,
1333
+ hir_self_ty : & ' tcx hir:: Ty < ' tcx > ,
1334
+ assoc_tag : ty:: AssocTag ,
1335
+ segment : & ' tcx hir:: PathSegment < ' tcx > ,
1336
+ qpath_hir_id : HirId ,
1337
+ span : Span ,
1338
+ variant_def_id : Option < DefId > ,
1339
+ ) -> Result < ( DefId , ty:: PolyTraitRef < ' tcx > ) , ErrorGuaranteed > {
1340
+ let tcx = self . tcx ( ) ;
1341
+
1285
1342
let self_ty_res = match hir_self_ty. kind {
1286
1343
hir:: TyKind :: Path ( hir:: QPath :: Resolved ( _, path) ) => path. res ,
1287
1344
_ => Res :: Err ,
1288
1345
} ;
1289
1346
1290
- // Find the type of the associated item, and the trait where the associated
1291
- // item is declared.
1347
+ // Find the type of the assoc item, and the trait where the associated item is declared.
1292
1348
let bound = match ( self_ty. kind ( ) , self_ty_res) {
1293
1349
( _, Res :: SelfTyAlias { alias_to : impl_def_id, is_trait_impl : true , .. } ) => {
1294
1350
// `Self` in an impl of a trait -- we have a concrete self type and a
@@ -1300,14 +1356,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1300
1356
1301
1357
self . probe_single_bound_for_assoc_item (
1302
1358
|| {
1303
- traits:: supertraits (
1304
- tcx,
1305
- ty:: Binder :: dummy ( trait_ref. instantiate_identity ( ) ) ,
1306
- )
1359
+ let trait_ref = ty:: Binder :: dummy ( trait_ref. instantiate_identity ( ) ) ;
1360
+ traits:: supertraits ( tcx, trait_ref)
1307
1361
} ,
1308
1362
AssocItemQSelf :: SelfTyAlias ,
1309
- mode . assoc_tag ( ) ,
1310
- ident,
1363
+ assoc_tag,
1364
+ segment . ident ,
1311
1365
span,
1312
1366
None ,
1313
1367
) ?
@@ -1318,55 +1372,28 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1318
1372
) => self . probe_single_ty_param_bound_for_assoc_item (
1319
1373
param_did. expect_local ( ) ,
1320
1374
hir_self_ty. span ,
1321
- mode . assoc_tag ( ) ,
1322
- ident,
1375
+ assoc_tag,
1376
+ segment . ident ,
1323
1377
span,
1324
1378
) ?,
1325
1379
_ => {
1326
1380
return Err ( self . report_unresolved_type_relative_path (
1327
1381
self_ty,
1328
1382
hir_self_ty,
1329
- mode . assoc_tag ( ) ,
1330
- ident,
1383
+ assoc_tag,
1384
+ segment . ident ,
1331
1385
qpath_hir_id,
1332
1386
span,
1333
1387
variant_def_id,
1334
1388
) ) ;
1335
1389
}
1336
1390
} ;
1337
1391
1338
- let trait_def_id = bound. def_id ( ) ;
1339
1392
let assoc_item = self
1340
- . probe_assoc_item ( ident, mode . assoc_tag ( ) , qpath_hir_id, span, trait_def_id )
1393
+ . probe_assoc_item ( segment . ident , assoc_tag, qpath_hir_id, span, bound . def_id ( ) )
1341
1394
. expect ( "failed to find associated item" ) ;
1342
- let ( def_id, args) = self . lower_assoc_item_path ( span, assoc_item. def_id , segment, bound) ?;
1343
- let result = TypeRelativePath :: AssocItem ( def_id, args) ;
1344
-
1345
- if let Some ( variant_def_id) = variant_def_id {
1346
- tcx. node_span_lint ( AMBIGUOUS_ASSOCIATED_ITEMS , qpath_hir_id, span, |lint| {
1347
- lint. primary_message ( "ambiguous associated item" ) ;
1348
- let mut could_refer_to = |kind : DefKind , def_id, also| {
1349
- let note_msg = format ! (
1350
- "`{}` could{} refer to the {} defined here" ,
1351
- ident,
1352
- also,
1353
- tcx. def_kind_descr( kind, def_id)
1354
- ) ;
1355
- lint. span_note ( tcx. def_span ( def_id) , note_msg) ;
1356
- } ;
1357
1395
1358
- could_refer_to ( DefKind :: Variant , variant_def_id, "" ) ;
1359
- could_refer_to ( mode. def_kind ( ) , assoc_item. def_id , " also" ) ;
1360
-
1361
- lint. span_suggestion (
1362
- span,
1363
- "use fully-qualified syntax" ,
1364
- format ! ( "<{} as {}>::{}" , self_ty, tcx. item_name( trait_def_id) , ident) ,
1365
- Applicability :: MachineApplicable ,
1366
- ) ;
1367
- } ) ;
1368
- }
1369
- Ok ( result)
1396
+ Ok ( ( assoc_item. def_id , bound) )
1370
1397
}
1371
1398
1372
1399
/// Search for inherent associated items for use at the type level.
0 commit comments