@@ -854,7 +854,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
854
854
}
855
855
856
856
// Returns `true` if a bounds list includes `?Sized`.
857
- pub fn is_unsized ( & self , ast_bounds : & [ hir:: GenericBound < ' _ > ] , span : Span ) -> bool {
857
+ fn is_unsized (
858
+ & self ,
859
+ ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
860
+ self_ty : Option < hir:: HirId > ,
861
+ where_clause : Option < & [ hir:: WherePredicate < ' _ > ] > ,
862
+ span : Span ,
863
+ ) -> bool {
858
864
let tcx = self . tcx ( ) ;
859
865
860
866
// Try to find an unbound in bounds.
@@ -868,11 +874,38 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
868
874
}
869
875
}
870
876
}
877
+ if let ( Some ( self_ty) , Some ( where_clause) ) = ( self_ty, where_clause) {
878
+ let self_ty_def_id = tcx. hir ( ) . local_def_id ( self_ty) . to_def_id ( ) ;
879
+ for clause in where_clause {
880
+ match clause {
881
+ hir:: WherePredicate :: BoundPredicate ( pred) => {
882
+ match pred. bounded_ty . kind {
883
+ hir:: TyKind :: Path ( hir:: QPath :: Resolved ( _, path) ) => match path. res {
884
+ Res :: Def ( DefKind :: TyParam , def_id) if def_id == self_ty_def_id => { }
885
+ _ => continue ,
886
+ } ,
887
+ _ => continue ,
888
+ }
889
+ for ab in pred. bounds {
890
+ if let hir:: GenericBound :: Trait ( ptr, hir:: TraitBoundModifier :: Maybe ) =
891
+ ab
892
+ {
893
+ if unbound. is_none ( ) {
894
+ unbound = Some ( & ptr. trait_ref ) ;
895
+ } else {
896
+ tcx. sess . emit_err ( MultipleRelaxedDefaultBounds { span } ) ;
897
+ }
898
+ }
899
+ }
900
+ }
901
+ _ => { }
902
+ }
903
+ }
904
+ }
871
905
872
906
let kind_id = tcx. lang_items ( ) . require ( LangItem :: Sized ) ;
873
907
match unbound {
874
908
Some ( tpb) => {
875
- // FIXME(#8559) currently requires the unbound to be built-in.
876
909
if let Ok ( kind_id) = kind_id {
877
910
if tpb. path . res != Res :: Def ( DefKind :: Trait , kind_id) {
878
911
tcx. sess . span_warn (
@@ -940,8 +973,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
940
973
false ,
941
974
) ;
942
975
}
943
- hir:: GenericBound :: Trait ( _, hir:: TraitBoundModifier :: Maybe )
944
- | hir:: GenericBound :: Unsized ( _) => { }
976
+ hir:: GenericBound :: Trait ( _, hir:: TraitBoundModifier :: Maybe ) => { }
945
977
hir:: GenericBound :: LangItemTrait ( lang_item, span, hir_id, args) => self
946
978
. instantiate_lang_item_trait_ref (
947
979
lang_item, span, hir_id, args, param_ty, bounds,
@@ -970,22 +1002,33 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
970
1002
/// example above, but is not true in supertrait listings like `trait Foo: Bar + Baz`.
971
1003
///
972
1004
/// `span` should be the declaration size of the parameter.
973
- pub fn compute_bounds (
1005
+ pub ( crate ) fn compute_bounds (
974
1006
& self ,
975
1007
param_ty : Ty < ' tcx > ,
976
1008
ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
1009
+ self_ty : Option < hir:: HirId > ,
1010
+ where_clause : Option < & [ hir:: WherePredicate < ' _ > ] > ,
977
1011
sized_by_default : SizedByDefault ,
978
1012
span : Span ,
979
1013
) -> Bounds < ' tcx > {
980
- self . compute_bounds_inner ( param_ty, & ast_bounds, sized_by_default, span)
1014
+ self . compute_bounds_inner (
1015
+ param_ty,
1016
+ & ast_bounds,
1017
+ self_ty,
1018
+ where_clause,
1019
+ sized_by_default,
1020
+ span,
1021
+ )
981
1022
}
982
1023
983
1024
/// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
984
1025
/// named `assoc_name` into ty::Bounds. Ignore the rest.
985
- pub fn compute_bounds_that_match_assoc_type (
1026
+ pub ( crate ) fn compute_bounds_that_match_assoc_type (
986
1027
& self ,
987
1028
param_ty : Ty < ' tcx > ,
988
1029
ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
1030
+ self_ty : Option < hir:: HirId > ,
1031
+ where_clause : Option < & [ hir:: WherePredicate < ' _ > ] > ,
989
1032
sized_by_default : SizedByDefault ,
990
1033
span : Span ,
991
1034
assoc_name : Ident ,
@@ -1002,13 +1045,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1002
1045
}
1003
1046
}
1004
1047
1005
- self . compute_bounds_inner ( param_ty, & result, sized_by_default, span)
1048
+ self . compute_bounds_inner ( param_ty, & result, self_ty , where_clause , sized_by_default, span)
1006
1049
}
1007
1050
1008
1051
fn compute_bounds_inner (
1009
1052
& self ,
1010
1053
param_ty : Ty < ' tcx > ,
1011
1054
ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
1055
+ self_ty : Option < hir:: HirId > ,
1056
+ where_clause : Option < & [ hir:: WherePredicate < ' _ > ] > ,
1012
1057
sized_by_default : SizedByDefault ,
1013
1058
span : Span ,
1014
1059
) -> Bounds < ' tcx > {
@@ -1017,7 +1062,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1017
1062
self . add_bounds ( param_ty, ast_bounds, & mut bounds, ty:: List :: empty ( ) ) ;
1018
1063
1019
1064
bounds. implicitly_sized = if let SizedByDefault :: Yes = sized_by_default {
1020
- if !self . is_unsized ( ast_bounds, span) { Some ( span) } else { None }
1065
+ if !self . is_unsized ( ast_bounds, self_ty, where_clause, span) {
1066
+ Some ( span)
1067
+ } else {
1068
+ None
1069
+ }
1021
1070
} else {
1022
1071
None
1023
1072
} ;
0 commit comments