@@ -38,8 +38,8 @@ use rustc_middle::middle::stability::AllowUnstable;
3838use rustc_middle:: mir:: interpret:: LitToConstInput ;
3939use rustc_middle:: ty:: print:: PrintPolyTraitRefExt as _;
4040use 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,
4343} ;
4444use rustc_middle:: { bug, span_bug} ;
4545use rustc_session:: lint:: builtin:: AMBIGUOUS_ASSOCIATED_ITEMS ;
@@ -937,7 +937,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
937937 fn probe_trait_that_defines_assoc_item (
938938 & self ,
939939 trait_def_id : DefId ,
940- assoc_tag : AssocTag ,
940+ assoc_tag : ty :: AssocTag ,
941941 assoc_ident : Ident ,
942942 ) -> bool {
943943 self . tcx ( )
@@ -980,7 +980,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
980980 & self ,
981981 ty_param_def_id : LocalDefId ,
982982 ty_param_span : Span ,
983- assoc_tag : AssocTag ,
983+ assoc_tag : ty :: AssocTag ,
984984 assoc_ident : Ident ,
985985 span : Span ,
986986 ) -> Result < ty:: PolyTraitRef < ' tcx > , ErrorGuaranteed > {
@@ -1015,7 +1015,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10151015 & self ,
10161016 all_candidates : impl Fn ( ) -> I ,
10171017 qself : AssocItemQSelf ,
1018- assoc_tag : AssocTag ,
1018+ assoc_tag : ty :: AssocTag ,
10191019 assoc_ident : Ident ,
10201020 span : Span ,
10211021 constraint : Option < & hir:: AssocItemConstraint < ' tcx > > ,
@@ -1238,7 +1238,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12381238 ) -> Result < TypeRelativePath < ' tcx > , ErrorGuaranteed > {
12391239 debug ! ( %self_ty, ?segment. ident) ;
12401240 let tcx = self . tcx ( ) ;
1241- let ident = segment. ident ;
12421241
12431242 // Check if we have an enum variant or an inherent associated type.
12441243 let mut variant_def_id = None ;
@@ -1247,7 +1246,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12471246 let variant_def = adt_def
12481247 . variants ( )
12491248 . 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 ( ) ) ) ;
12511250 if let Some ( variant_def) = variant_def {
12521251 if let PermitVariants :: Yes = mode. permit_variants ( ) {
12531252 tcx. check_stability ( variant_def. def_id , Some ( qpath_hir_id) , span, None ) ;
@@ -1282,13 +1281,70 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12821281 }
12831282 }
12841283
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+
12851342 let self_ty_res = match hir_self_ty. kind {
12861343 hir:: TyKind :: Path ( hir:: QPath :: Resolved ( _, path) ) => path. res ,
12871344 _ => Res :: Err ,
12881345 } ;
12891346
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.
12921348 let bound = match ( self_ty. kind ( ) , self_ty_res) {
12931349 ( _, Res :: SelfTyAlias { alias_to : impl_def_id, is_trait_impl : true , .. } ) => {
12941350 // `Self` in an impl of a trait -- we have a concrete self type and a
@@ -1300,14 +1356,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
13001356
13011357 self . probe_single_bound_for_assoc_item (
13021358 || {
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)
13071361 } ,
13081362 AssocItemQSelf :: SelfTyAlias ,
1309- mode . assoc_tag ( ) ,
1310- ident,
1363+ assoc_tag,
1364+ segment . ident ,
13111365 span,
13121366 None ,
13131367 ) ?
@@ -1318,55 +1372,28 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
13181372 ) => self . probe_single_ty_param_bound_for_assoc_item (
13191373 param_did. expect_local ( ) ,
13201374 hir_self_ty. span ,
1321- mode . assoc_tag ( ) ,
1322- ident,
1375+ assoc_tag,
1376+ segment . ident ,
13231377 span,
13241378 ) ?,
13251379 _ => {
13261380 return Err ( self . report_unresolved_type_relative_path (
13271381 self_ty,
13281382 hir_self_ty,
1329- mode . assoc_tag ( ) ,
1330- ident,
1383+ assoc_tag,
1384+ segment . ident ,
13311385 qpath_hir_id,
13321386 span,
13331387 variant_def_id,
13341388 ) ) ;
13351389 }
13361390 } ;
13371391
1338- let trait_def_id = bound. def_id ( ) ;
13391392 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 ( ) )
13411394 . 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- } ;
13571395
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) )
13701397 }
13711398
13721399 /// Search for inherent associated items for use at the type level.
0 commit comments