@@ -26,23 +26,36 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
26
26
span : Span ,
27
27
) {
28
28
let tcx = self . tcx ( ) ;
29
+ let sized_def_id = tcx. lang_items ( ) . sized_trait ( ) ;
30
+ let mut seen_negative_sized_bound = false ;
29
31
30
32
// Try to find an unbound in bounds.
31
33
let mut unbounds: SmallVec < [ _ ; 1 ] > = SmallVec :: new ( ) ;
32
34
let mut search_bounds = |ast_bounds : & ' tcx [ hir:: GenericBound < ' tcx > ] | {
33
35
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
+ _ => { }
36
49
}
37
50
}
38
51
} ;
39
52
search_bounds ( ast_bounds) ;
40
53
if let Some ( ( self_ty, where_clause) ) = self_ty_where_predicates {
41
54
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 ) ;
46
59
}
47
60
}
48
61
}
@@ -53,15 +66,13 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
53
66
} ) ;
54
67
}
55
68
56
- let sized_def_id = tcx. lang_items ( ) . sized_trait ( ) ;
57
-
58
69
let mut seen_sized_unbound = false ;
59
70
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 ;
65
76
}
66
77
// There was a `?Trait` bound, but it was not `?Sized`; warn.
67
78
tcx. dcx ( ) . span_warn (
@@ -71,15 +82,12 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
71
82
) ;
72
83
}
73
84
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.
83
91
bounds. push_sized ( tcx, self_ty, span) ;
84
92
}
85
93
}
0 commit comments