@@ -719,8 +719,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
719
719
speculative : bool )
720
720
-> ty:: PolyTraitRef < ' tcx >
721
721
{
722
- let tcx = self . tcx ( ) ;
723
-
724
722
let trait_def_id = self . trait_def_id ( trait_ref) ;
725
723
726
724
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 {
734
732
trait_ref. path . segments . last ( ) . unwrap ( ) ) ;
735
733
let poly_trait_ref = ty:: Binder :: bind ( ty:: TraitRef :: new ( trait_def_id, substs) ) ;
736
734
735
+ let mut dup_bindings = FxHashMap :: default ( ) ;
737
736
poly_projections. extend ( assoc_bindings. iter ( ) . filter_map ( |binding| {
738
737
// specify type to assert that error was already reported in Err case:
739
738
let predicate: Result < _ , ErrorReported > =
740
739
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 ) ;
742
741
// okay to ignore Err because of ErrorReported (see above)
743
742
Some ( ( predicate. ok ( ) ?, binding. span ) )
744
743
} ) ) ;
745
744
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
-
805
745
debug ! ( "instantiate_poly_trait_ref({:?}, projections={:?}) -> {:?}" ,
806
746
trait_ref, poly_projections, poly_trait_ref) ;
807
747
poly_trait_ref
@@ -884,7 +824,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
884
824
ref_id : ast:: NodeId ,
885
825
trait_ref : ty:: PolyTraitRef < ' tcx > ,
886
826
binding : & ConvertedBinding < ' tcx > ,
887
- speculative : bool )
827
+ speculative : bool ,
828
+ dup_bindings : & mut FxHashMap < DefId , Span > )
888
829
-> Result < ty:: PolyProjectionPredicate < ' tcx > , ErrorReported >
889
830
{
890
831
let tcx = self . tcx ( ) ;
@@ -948,7 +889,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
948
889
let candidates = traits:: supertraits ( tcx, trait_ref) . filter ( |r| {
949
890
self . trait_defines_associated_type_named ( r. def_id ( ) , binding. item_name )
950
891
} ) ;
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 ( ) ,
952
893
binding. item_name , binding. span )
953
894
} ?;
954
895
@@ -964,6 +905,21 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
964
905
}
965
906
tcx. check_stability ( assoc_ty. def_id , Some ( ref_id) , binding. span ) ;
966
907
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
+
967
923
Ok ( candidate. map_bound ( |trait_ref| {
968
924
ty:: ProjectionPredicate {
969
925
projection_ty : ty:: ProjectionTy :: from_ref_and_name (
@@ -989,6 +945,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
989
945
)
990
946
}
991
947
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
+
992
956
fn conv_object_ty_poly_trait_ref ( & self ,
993
957
span : Span ,
994
958
trait_bounds : & [ hir:: PolyTraitRef ] ,
@@ -1043,13 +1007,22 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
1043
1007
// Use a `BTreeSet` to keep output in a more consistent order.
1044
1008
let mut associated_types = BTreeSet :: default ( ) ;
1045
1009
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
+ }
1050
1023
}
1051
1024
1052
- for ( projection_bound, _) in projection_bounds. iter ( ) . rev ( ) {
1025
+ for ( projection_bound, _) in & projection_bounds {
1053
1026
associated_types. remove ( & projection_bound. projection_def_id ( ) ) ;
1054
1027
}
1055
1028
@@ -1067,13 +1040,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
1067
1040
1068
1041
// Erase the `dummy_self` (`TRAIT_OBJECT_DUMMY_SELF`) used above.
1069
1042
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)
1072
1044
} ) ;
1073
1045
let existential_projections = projection_bounds. iter ( ) . map ( |( bound, _) | {
1074
1046
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) ) ;
1077
1048
ty:: ExistentialProjection {
1078
1049
ty : b. ty ,
1079
1050
item_def_id : b. projection_ty . item_def_id ,
0 commit comments