@@ -26,23 +26,36 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
2626 span : Span ,
2727 ) {
2828 let tcx = self . tcx ( ) ;
29+ let sized_def_id = tcx. lang_items ( ) . sized_trait ( ) ;
30+ let mut seen_negative_sized_bound = false ;
2931
3032 // Try to find an unbound in bounds.
3133 let mut unbounds: SmallVec < [ _ ; 1 ] > = SmallVec :: new ( ) ;
3234 let mut search_bounds = |ast_bounds : & ' tcx [ hir:: GenericBound < ' tcx > ] | {
3335 for ab in ast_bounds {
34- if let hir:: GenericBound :: Trait ( ptr, hir:: TraitBoundModifier :: Maybe ) = ab {
35- unbounds. push ( ptr)
36+ let hir:: GenericBound :: Trait ( ptr, modifier) = ab else {
37+ continue ;
38+ } ;
39+ match modifier {
40+ hir:: TraitBoundModifier :: Maybe => unbounds. push ( ptr) ,
41+ hir:: TraitBoundModifier :: Negative => {
42+ if let Some ( sized_def_id) = sized_def_id
43+ && ptr. trait_ref . path . res == Res :: Def ( DefKind :: Trait , sized_def_id)
44+ {
45+ seen_negative_sized_bound = true ;
46+ }
47+ }
48+ _ => { }
3649 }
3750 }
3851 } ;
3952 search_bounds ( ast_bounds) ;
4053 if let Some ( ( self_ty, where_clause) ) = self_ty_where_predicates {
4154 for clause in where_clause {
42- if let hir:: WherePredicate :: BoundPredicate ( pred) = clause {
43- if pred. is_param_bound ( self_ty. to_def_id ( ) ) {
44- search_bounds ( pred . bounds ) ;
45- }
55+ if let hir:: WherePredicate :: BoundPredicate ( pred) = clause
56+ && pred. is_param_bound ( self_ty. to_def_id ( ) )
57+ {
58+ search_bounds ( pred . bounds ) ;
4659 }
4760 }
4861 }
@@ -53,15 +66,13 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
5366 } ) ;
5467 }
5568
56- let sized_def_id = tcx. lang_items ( ) . sized_trait ( ) ;
57-
5869 let mut seen_sized_unbound = false ;
5970 for unbound in unbounds {
60- if let Some ( sized_def_id) = sized_def_id {
61- if unbound. trait_ref . path . res == Res :: Def ( DefKind :: Trait , sized_def_id) {
62- seen_sized_unbound = true ;
63- continue ;
64- }
71+ if let Some ( sized_def_id) = sized_def_id
72+ && unbound. trait_ref . path . res == Res :: Def ( DefKind :: Trait , sized_def_id)
73+ {
74+ seen_sized_unbound = true ;
75+ continue ;
6576 }
6677 // There was a `?Trait` bound, but it was not `?Sized`; warn.
6778 tcx. dcx ( ) . span_warn (
@@ -71,15 +82,12 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
7182 ) ;
7283 }
7384
74- // If the above loop finished there was no `?Sized` bound; add implicitly sized if `Sized` is available.
75- if sized_def_id. is_none ( ) {
76- // No lang item for `Sized`, so we can't add it as a bound.
77- return ;
78- }
79- if seen_sized_unbound {
80- // There was in fact a `?Sized` bound, return without doing anything
81- } else {
82- // There was no `?Sized` bound; add implicitly sized if `Sized` is available.
85+ if seen_sized_unbound || seen_negative_sized_bound {
86+ // There was in fact a `?Sized` or `!Sized` bound;
87+ // we don't need to do anything.
88+ } else if sized_def_id. is_some ( ) {
89+ // There was no `?Sized` or `!Sized` bound;
90+ // add `Sized` if it's available.
8391 bounds. push_sized ( tcx, self_ty, span) ;
8492 }
8593 }
0 commit comments