@@ -370,7 +370,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
370
370
poly_projections. extend ( assoc_bindings. iter ( ) . filter_map ( |binding| {
371
371
// specify type to assert that error was already reported in Err case:
372
372
let predicate: Result < _ , ErrorReported > =
373
- self . ast_type_binding_to_poly_projection_predicate ( poly_trait_ref, binding) ;
373
+ self . ast_type_binding_to_poly_projection_predicate ( trait_ref. ref_id , poly_trait_ref,
374
+ binding) ;
374
375
predicate. ok ( ) // ok to ignore Err() because ErrorReported (see above)
375
376
} ) ) ;
376
377
@@ -442,6 +443,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
442
443
443
444
fn ast_type_binding_to_poly_projection_predicate (
444
445
& self ,
446
+ ref_id : ast:: NodeId ,
445
447
trait_ref : ty:: PolyTraitRef < ' tcx > ,
446
448
binding : & ConvertedBinding < ' tcx > )
447
449
-> Result < ty:: PolyProjectionPredicate < ' tcx > , ErrorReported >
@@ -494,30 +496,30 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
494
496
. emit ( ) ;
495
497
}
496
498
497
- // Simple case: X is defined in the current trait.
498
- if self . trait_defines_associated_type_named ( trait_ref. def_id ( ) , binding. item_name ) {
499
- return Ok ( trait_ref. map_bound ( |trait_ref| {
500
- ty:: ProjectionPredicate {
501
- projection_ty : ty:: ProjectionTy :: from_ref_and_name (
502
- tcx,
503
- trait_ref,
504
- binding. item_name ,
505
- ) ,
506
- ty : binding. ty ,
507
- }
508
- } ) ) ;
499
+ let candidate = if self . trait_defines_associated_type_named ( trait_ref. def_id ( ) ,
500
+ binding. item_name ) {
501
+ // Simple case: X is defined in the current trait.
502
+ Ok ( trait_ref)
503
+ } else {
504
+ // Otherwise, we have to walk through the supertraits to find
505
+ // those that do.
506
+ let candidates = traits:: supertraits ( tcx, trait_ref) . filter ( |r| {
507
+ self . trait_defines_associated_type_named ( r. def_id ( ) , binding. item_name )
508
+ } ) ;
509
+ self . one_bound_for_assoc_type ( candidates, & trait_ref. to_string ( ) ,
510
+ binding. item_name , binding. span )
511
+ } ?;
512
+
513
+ let ( assoc_ident, def_scope) = tcx. adjust ( binding. item_name , candidate. def_id ( ) , ref_id) ;
514
+ let assoc_ty = tcx. associated_items ( candidate. def_id ( ) ) . find ( |i| {
515
+ i. kind == ty:: AssociatedKind :: Type && i. name . to_ident ( ) == assoc_ident
516
+ } ) . expect ( "missing associated type" ) ;
517
+
518
+ if !assoc_ty. vis . is_accessible_from ( def_scope, tcx) {
519
+ let msg = format ! ( "associated type `{}` is private" , binding. item_name) ;
520
+ tcx. sess . span_err ( binding. span , & msg) ;
509
521
}
510
-
511
- // Otherwise, we have to walk through the supertraits to find
512
- // those that do.
513
- let candidates =
514
- traits:: supertraits ( tcx, trait_ref. clone ( ) )
515
- . filter ( |r| self . trait_defines_associated_type_named ( r. def_id ( ) , binding. item_name ) ) ;
516
-
517
- let candidate = self . one_bound_for_assoc_type ( candidates,
518
- & trait_ref. to_string ( ) ,
519
- binding. item_name ,
520
- binding. span ) ?;
522
+ tcx. check_stability ( assoc_ty. def_id , ref_id, binding. span ) ;
521
523
522
524
Ok ( candidate. map_bound ( |trait_ref| {
523
525
ty:: ProjectionPredicate {
0 commit comments