@@ -854,7 +854,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
854854 }
855855
856856 // 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 {
858864 let tcx = self . tcx ( ) ;
859865
860866 // Try to find an unbound in bounds.
@@ -868,11 +874,38 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
868874 }
869875 }
870876 }
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+ }
871905
872906 let kind_id = tcx. lang_items ( ) . require ( LangItem :: Sized ) ;
873907 match unbound {
874908 Some ( tpb) => {
875- // FIXME(#8559) currently requires the unbound to be built-in.
876909 if let Ok ( kind_id) = kind_id {
877910 if tpb. path . res != Res :: Def ( DefKind :: Trait , kind_id) {
878911 tcx. sess . span_warn (
@@ -940,8 +973,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
940973 false ,
941974 ) ;
942975 }
943- hir:: GenericBound :: Trait ( _, hir:: TraitBoundModifier :: Maybe )
944- | hir:: GenericBound :: Unsized ( _) => { }
976+ hir:: GenericBound :: Trait ( _, hir:: TraitBoundModifier :: Maybe ) => { }
945977 hir:: GenericBound :: LangItemTrait ( lang_item, span, hir_id, args) => self
946978 . instantiate_lang_item_trait_ref (
947979 lang_item, span, hir_id, args, param_ty, bounds,
@@ -970,22 +1002,33 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
9701002 /// example above, but is not true in supertrait listings like `trait Foo: Bar + Baz`.
9711003 ///
9721004 /// `span` should be the declaration size of the parameter.
973- pub fn compute_bounds (
1005+ pub ( crate ) fn compute_bounds (
9741006 & self ,
9751007 param_ty : Ty < ' tcx > ,
9761008 ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
1009+ self_ty : Option < hir:: HirId > ,
1010+ where_clause : Option < & [ hir:: WherePredicate < ' _ > ] > ,
9771011 sized_by_default : SizedByDefault ,
9781012 span : Span ,
9791013 ) -> 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+ )
9811022 }
9821023
9831024 /// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
9841025 /// 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 (
9861027 & self ,
9871028 param_ty : Ty < ' tcx > ,
9881029 ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
1030+ self_ty : Option < hir:: HirId > ,
1031+ where_clause : Option < & [ hir:: WherePredicate < ' _ > ] > ,
9891032 sized_by_default : SizedByDefault ,
9901033 span : Span ,
9911034 assoc_name : Ident ,
@@ -1002,13 +1045,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10021045 }
10031046 }
10041047
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)
10061049 }
10071050
10081051 fn compute_bounds_inner (
10091052 & self ,
10101053 param_ty : Ty < ' tcx > ,
10111054 ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
1055+ self_ty : Option < hir:: HirId > ,
1056+ where_clause : Option < & [ hir:: WherePredicate < ' _ > ] > ,
10121057 sized_by_default : SizedByDefault ,
10131058 span : Span ,
10141059 ) -> Bounds < ' tcx > {
@@ -1017,7 +1062,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10171062 self . add_bounds ( param_ty, ast_bounds, & mut bounds, ty:: List :: empty ( ) ) ;
10181063
10191064 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+ }
10211070 } else {
10221071 None
10231072 } ;
0 commit comments