@@ -719,8 +719,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
719719 speculative : bool )
720720 -> ty:: PolyTraitRef < ' tcx >
721721 {
722- let tcx = self . tcx ( ) ;
723-
724722 let trait_def_id = self . trait_def_id ( trait_ref) ;
725723
726724 debug ! ( "instantiate_poly_trait_ref({:?}, def_id={:?})" , trait_ref, trait_def_id) ;
@@ -734,74 +732,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
734732 trait_ref. path . segments . last ( ) . unwrap ( ) ) ;
735733 let poly_trait_ref = ty:: Binder :: bind ( ty:: TraitRef :: new ( trait_def_id, substs) ) ;
736734
735+ let mut dup_bindings = FxHashMap :: default ( ) ;
737736 poly_projections. extend ( assoc_bindings. iter ( ) . filter_map ( |binding| {
738737 // specify type to assert that error was already reported in Err case:
739738 let predicate: Result < _ , ErrorReported > =
740739 self . ast_type_binding_to_poly_projection_predicate (
741- trait_ref. ref_id , poly_trait_ref, binding, speculative) ;
740+ trait_ref. ref_id , poly_trait_ref, binding, speculative, & mut dup_bindings ) ;
742741 // okay to ignore Err because of ErrorReported (see above)
743742 Some ( ( predicate. ok ( ) ?, binding. span ) )
744743 } ) ) ;
745744
746- // make flat_map:
747- // for tr in traits::supertraits(tcx, poly_trait_ref) {
748- // let sup_trait_ref = tr.skip_binder();
749- // poly_projections.extend(sup_trait_ref.substs.types().filter_map(|t| {
750- // if let TyKind::Projection(proj) = t.sty {
751- // Some((proj, span))
752- // } else {
753- // None
754- // }
755- // });
756- // }
757-
758- // Include all projections from associated type bindings of supertraits.
759- poly_projections. extend ( traits:: elaborate_trait_ref ( tcx, poly_trait_ref)
760- . into_iter ( )
761- . filter_map ( |pred| {
762- if let ty:: Predicate :: Projection ( proj) = pred {
763- Some ( proj)
764- } else {
765- None
766- }
767- } )
768- . map ( |proj| ( proj, DUMMY_SP ) )
769- ) ;
770-
771- // // Include associated type bindings from supertraits.
772- // let mut foo = poly_projections.clone();
773- // foo.extend(tcx.predicates_of(trait_def_id)
774- // .predicates.into_iter()
775- // .filter_map(|(pred, span)| {
776- // debug!("pred: {:?}", pred);
777- // if let ty::Predicate::Projection(proj) = pred {
778- // Some((proj, span))
779- // } else {
780- // None
781- // }
782- // }));
783-
784- // Check for multiple bindings of associated types.
785- let mut seen_projection_bounds = FxHashMap :: default ( ) ;
786- for ( projection_bound, span) in poly_projections. iter ( ) . rev ( ) {
787- let bound_def_id = projection_bound. projection_def_id ( ) ;
788- let assoc_item = tcx. associated_item ( bound_def_id) ;
789- let trait_def_id = assoc_item. container . id ( ) ;
790- // let trait_ref = tcx.associated_item(proj.projection_type.item_def_id).container;
791- seen_projection_bounds. entry ( ( assoc_item. def_id , bound_def_id) )
792- . and_modify ( |prev_span| {
793- struct_span_err ! ( tcx. sess, * span, E0719 ,
794- "the value of the associated type `{}` (from the trait `{}`) \
795- is already specified",
796- assoc_item. ident,
797- tcx. item_path_str( trait_def_id) )
798- . span_label ( * span, "re-bound here" )
799- . span_label ( * prev_span, format ! ( "`{}` bound here first" , assoc_item. ident) )
800- . emit ( ) ;
801- } )
802- . or_insert ( * span) ;
803- }
804-
805745 debug ! ( "instantiate_poly_trait_ref({:?}, projections={:?}) -> {:?}" ,
806746 trait_ref, poly_projections, poly_trait_ref) ;
807747 poly_trait_ref
@@ -884,7 +824,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
884824 ref_id : ast:: NodeId ,
885825 trait_ref : ty:: PolyTraitRef < ' tcx > ,
886826 binding : & ConvertedBinding < ' tcx > ,
887- speculative : bool )
827+ speculative : bool ,
828+ dup_bindings : & mut FxHashMap < DefId , Span > )
888829 -> Result < ty:: PolyProjectionPredicate < ' tcx > , ErrorReported >
889830 {
890831 let tcx = self . tcx ( ) ;
@@ -948,7 +889,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
948889 let candidates = traits:: supertraits ( tcx, trait_ref) . filter ( |r| {
949890 self . trait_defines_associated_type_named ( r. def_id ( ) , binding. item_name )
950891 } ) ;
951- self . one_bound_for_assoc_type ( candidates. into_iter ( ) , & trait_ref. to_string ( ) ,
892+ self . one_bound_for_assoc_type ( candidates, & trait_ref. to_string ( ) ,
952893 binding. item_name , binding. span )
953894 } ?;
954895
@@ -964,6 +905,21 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
964905 }
965906 tcx. check_stability ( assoc_ty. def_id , Some ( ref_id) , binding. span ) ;
966907
908+ if !speculative {
909+ dup_bindings. entry ( assoc_ty. def_id )
910+ . and_modify ( |prev_span| {
911+ struct_span_err ! ( self . tcx( ) . sess, binding. span, E0719 ,
912+ "the value of the associated type `{}` (from the trait `{}`) \
913+ is already specified",
914+ binding. item_name,
915+ tcx. item_path_str( assoc_ty. container. id( ) ) )
916+ . span_label ( binding. span , "re-bound here" )
917+ . span_label ( * prev_span, format ! ( "`{}` bound here first" , binding. item_name) )
918+ . emit ( ) ;
919+ } )
920+ . or_insert ( binding. span ) ;
921+ }
922+
967923 Ok ( candidate. map_bound ( |trait_ref| {
968924 ty:: ProjectionPredicate {
969925 projection_ty : ty:: ProjectionTy :: from_ref_and_name (
@@ -989,6 +945,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
989945 )
990946 }
991947
948+ /// Transform a `PolyTraitRef` into a `PolyExistentialTraitRef` by
949+ /// removing the dummy `Self` type (`TRAIT_OBJECT_DUMMY_SELF`).
950+ fn trait_ref_to_existential ( & self , trait_ref : ty:: TraitRef < ' tcx > )
951+ -> ty:: ExistentialTraitRef < ' tcx > {
952+ assert_eq ! ( trait_ref. self_ty( ) . sty, TRAIT_OBJECT_DUMMY_SELF ) ;
953+ ty:: ExistentialTraitRef :: erase_self_ty ( self . tcx ( ) , trait_ref)
954+ }
955+
992956 fn conv_object_ty_poly_trait_ref ( & self ,
993957 span : Span ,
994958 trait_bounds : & [ hir:: PolyTraitRef ] ,
@@ -1043,13 +1007,22 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
10431007 // Use a `BTreeSet` to keep output in a more consistent order.
10441008 let mut associated_types = BTreeSet :: default ( ) ;
10451009
1046- for tr in traits:: supertraits ( tcx, principal) {
1047- associated_types. extend ( tcx. associated_items ( tr. def_id ( ) )
1048- . filter ( |item| item. kind == ty:: AssociatedKind :: Type )
1049- . map ( |item| item. def_id ) ) ;
1010+ for tr in traits:: elaborate_trait_ref ( tcx, principal) {
1011+ match tr {
1012+ ty:: Predicate :: Trait ( pred) => {
1013+ associated_types. extend ( tcx. associated_items ( pred. def_id ( ) )
1014+ . filter ( |item| item. kind == ty:: AssociatedKind :: Type )
1015+ . map ( |item| item. def_id ) ) ;
1016+ }
1017+ ty:: Predicate :: Projection ( pred) => {
1018+ // Include projections defined on supertraits.
1019+ projection_bounds. push ( ( pred, DUMMY_SP ) )
1020+ }
1021+ _ => ( )
1022+ }
10501023 }
10511024
1052- for ( projection_bound, _) in projection_bounds. iter ( ) . rev ( ) {
1025+ for ( projection_bound, _) in & projection_bounds {
10531026 associated_types. remove ( & projection_bound. projection_def_id ( ) ) ;
10541027 }
10551028
@@ -1067,13 +1040,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
10671040
10681041 // Erase the `dummy_self` (`TRAIT_OBJECT_DUMMY_SELF`) used above.
10691042 let existential_principal = principal. map_bound ( |trait_ref| {
1070- assert_eq ! ( trait_ref. self_ty( ) . sty, TRAIT_OBJECT_DUMMY_SELF ) ;
1071- ty:: ExistentialTraitRef :: erase_self_ty ( self . tcx ( ) , trait_ref)
1043+ self . trait_ref_to_existential ( trait_ref)
10721044 } ) ;
10731045 let existential_projections = projection_bounds. iter ( ) . map ( |( bound, _) | {
10741046 bound. map_bound ( |b| {
1075- let trait_ref = ty:: ExistentialTraitRef :: erase_self_ty ( self . tcx ( ) ,
1076- b. projection_ty . trait_ref ( tcx) ) ;
1047+ let trait_ref = self . trait_ref_to_existential ( b. projection_ty . trait_ref ( tcx) ) ;
10771048 ty:: ExistentialProjection {
10781049 ty : b. ty ,
10791050 item_def_id : b. projection_ty . item_def_id ,
0 commit comments