@@ -370,7 +370,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
370370 poly_projections. extend ( assoc_bindings. iter ( ) . filter_map ( |binding| {
371371 // specify type to assert that error was already reported in Err case:
372372 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) ;
374375 predicate. ok ( ) // ok to ignore Err() because ErrorReported (see above)
375376 } ) ) ;
376377
@@ -442,6 +443,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
442443
443444 fn ast_type_binding_to_poly_projection_predicate (
444445 & self ,
446+ ref_id : ast:: NodeId ,
445447 trait_ref : ty:: PolyTraitRef < ' tcx > ,
446448 binding : & ConvertedBinding < ' tcx > )
447449 -> Result < ty:: PolyProjectionPredicate < ' tcx > , ErrorReported >
@@ -494,30 +496,30 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
494496 . emit ( ) ;
495497 }
496498
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) ;
509521 }
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 ) ;
521523
522524 Ok ( candidate. map_bound ( |trait_ref| {
523525 ty:: ProjectionPredicate {
0 commit comments