@@ -278,6 +278,17 @@ impl ItemCtxt<'tcx> {
278
278
pub fn to_ty ( & self , ast_ty : & ' tcx hir:: Ty < ' tcx > ) -> Ty < ' tcx > {
279
279
AstConv :: ast_ty_to_ty ( self , ast_ty)
280
280
}
281
+
282
+ pub fn hir_id ( & self ) -> hir:: HirId {
283
+ self . tcx
284
+ . hir ( )
285
+ . as_local_hir_id ( self . item_def_id )
286
+ . expect ( "Non-local call to local provider is_const_fn" )
287
+ }
288
+
289
+ pub fn node ( & self ) -> hir:: Node < ' tcx > {
290
+ self . tcx . hir ( ) . get ( self . hir_id ( ) )
291
+ }
281
292
}
282
293
283
294
impl AstConv < ' tcx > for ItemCtxt < ' tcx > {
@@ -290,15 +301,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
290
301
}
291
302
292
303
fn default_constness_for_trait_bounds ( & self ) -> ast:: Constness {
293
- // FIXME: refactor this into a method
294
- let hir_id = self
295
- . tcx
296
- . hir ( )
297
- . as_local_hir_id ( self . item_def_id )
298
- . expect ( "Non-local call to local provider is_const_fn" ) ;
299
-
300
- let node = self . tcx . hir ( ) . get ( hir_id) ;
301
- if let Some ( fn_like) = FnLikeNode :: from_node ( node) {
304
+ if let Some ( fn_like) = FnLikeNode :: from_node ( self . node ( ) ) {
302
305
fn_like. constness ( )
303
306
} else {
304
307
ast:: Constness :: NotConst
@@ -352,14 +355,42 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
352
355
self . tcx ( ) . mk_projection ( item_def_id, item_substs)
353
356
} else {
354
357
// There are no late-bound regions; we can just ignore the binder.
355
- struct_span_err ! (
358
+ let mut err = struct_span_err ! (
356
359
self . tcx( ) . sess,
357
360
span,
358
361
E0212 ,
359
362
"cannot extract an associated type from a higher-ranked trait bound \
360
363
in this context"
361
- )
362
- . emit ( ) ;
364
+ ) ;
365
+
366
+ match self . node ( ) {
367
+ hir:: Node :: Field ( _)
368
+ | hir:: Node :: Variant ( _)
369
+ | hir:: Node :: Ctor ( _)
370
+ | hir:: Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Struct ( ..) , .. } )
371
+ | hir:: Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Enum ( ..) , .. } )
372
+ | hir:: Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Union ( ..) , .. } ) => {
373
+ // The suggestion is only valid if this is not an ADT.
374
+ }
375
+ hir:: Node :: Item ( _)
376
+ | hir:: Node :: ForeignItem ( _)
377
+ | hir:: Node :: TraitItem ( _)
378
+ | hir:: Node :: ImplItem ( _) => {
379
+ err. span_suggestion (
380
+ span,
381
+ "use a fully qualified path with inferred lifetimes" ,
382
+ format ! (
383
+ "{}::{}" ,
384
+ // Erase named lt, we want `<A as B<'_>::C`, not `<A as B<'a>::C`.
385
+ self . tcx. anonymize_late_bound_regions( & poly_trait_ref) . skip_binder( ) ,
386
+ item_segment. ident
387
+ ) ,
388
+ Applicability :: MaybeIncorrect ,
389
+ ) ;
390
+ }
391
+ _ => { }
392
+ }
393
+ err. emit ( ) ;
363
394
self . tcx ( ) . types . err
364
395
}
365
396
}
0 commit comments