@@ -18,11 +18,10 @@ use rustc_trait_selection::traits;
1818use smallvec:: SmallVec ;
1919use tracing:: { debug, instrument} ;
2020
21- use super :: errors:: GenericsArgsErrExtend ;
2221use crate :: errors;
2322use crate :: hir_ty_lowering:: {
24- AssocItemQSelf , FeedConstTy , HirTyLowerer , OverlappingAsssocItemConstraints , PredicateFilter ,
25- RegionInferReason ,
23+ AssocItemQSelf , FeedConstTy , GenericsArgsErrExtend , HirTyLowerer , ImpliedBoundsContext ,
24+ OverlappingAsssocItemConstraints , PredicateFilter , RegionInferReason ,
2625} ;
2726
2827#[ derive( Debug , Default ) ]
@@ -62,7 +61,7 @@ impl CollectedSizednessBounds {
6261
6362fn search_bounds_for < ' tcx > (
6463 hir_bounds : & ' tcx [ hir:: GenericBound < ' tcx > ] ,
65- self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir :: WherePredicate < ' tcx > ] ) > ,
64+ context : ImpliedBoundsContext < ' tcx > ,
6665 mut f : impl FnMut ( & ' tcx PolyTraitRef < ' tcx > ) ,
6766) {
6867 let mut search_bounds = |hir_bounds : & ' tcx [ hir:: GenericBound < ' tcx > ] | {
@@ -76,7 +75,7 @@ fn search_bounds_for<'tcx>(
7675 } ;
7776
7877 search_bounds ( hir_bounds) ;
79- if let Some ( ( self_ty, where_clause) ) = self_ty_where_predicates {
78+ if let ImpliedBoundsContext :: TyParam ( self_ty, where_clause) = context {
8079 for clause in where_clause {
8180 if let hir:: WherePredicateKind :: BoundPredicate ( pred) = clause. kind
8281 && pred. is_param_bound ( self_ty. to_def_id ( ) )
@@ -89,10 +88,10 @@ fn search_bounds_for<'tcx>(
8988
9089fn collect_relaxed_bounds < ' tcx > (
9190 hir_bounds : & ' tcx [ hir:: GenericBound < ' tcx > ] ,
92- self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir :: WherePredicate < ' tcx > ] ) > ,
91+ context : ImpliedBoundsContext < ' tcx > ,
9392) -> SmallVec < [ & ' tcx PolyTraitRef < ' tcx > ; 1 ] > {
9493 let mut relaxed_bounds: SmallVec < [ _ ; 1 ] > = SmallVec :: new ( ) ;
95- search_bounds_for ( hir_bounds, self_ty_where_predicates , |ptr| {
94+ search_bounds_for ( hir_bounds, context , |ptr| {
9695 if matches ! ( ptr. modifiers. polarity, hir:: BoundPolarity :: Maybe ( _) ) {
9796 relaxed_bounds. push ( ptr) ;
9897 }
@@ -102,11 +101,11 @@ fn collect_relaxed_bounds<'tcx>(
102101
103102fn collect_bounds < ' a , ' tcx > (
104103 hir_bounds : & ' a [ hir:: GenericBound < ' tcx > ] ,
105- self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir :: WherePredicate < ' tcx > ] ) > ,
104+ context : ImpliedBoundsContext < ' tcx > ,
106105 target_did : DefId ,
107106) -> CollectedBound {
108107 let mut collect_into = CollectedBound :: default ( ) ;
109- search_bounds_for ( hir_bounds, self_ty_where_predicates , |ptr| {
108+ search_bounds_for ( hir_bounds, context , |ptr| {
110109 if !matches ! ( ptr. trait_ref. path. res, Res :: Def ( DefKind :: Trait , did) if did == target_did) {
111110 return ;
112111 }
@@ -123,17 +122,17 @@ fn collect_bounds<'a, 'tcx>(
123122fn collect_sizedness_bounds < ' tcx > (
124123 tcx : TyCtxt < ' tcx > ,
125124 hir_bounds : & ' tcx [ hir:: GenericBound < ' tcx > ] ,
126- self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir :: WherePredicate < ' tcx > ] ) > ,
125+ context : ImpliedBoundsContext < ' tcx > ,
127126 span : Span ,
128127) -> CollectedSizednessBounds {
129128 let sized_did = tcx. require_lang_item ( hir:: LangItem :: Sized , span) ;
130- let sized = collect_bounds ( hir_bounds, self_ty_where_predicates , sized_did) ;
129+ let sized = collect_bounds ( hir_bounds, context , sized_did) ;
131130
132131 let meta_sized_did = tcx. require_lang_item ( hir:: LangItem :: MetaSized , span) ;
133- let meta_sized = collect_bounds ( hir_bounds, self_ty_where_predicates , meta_sized_did) ;
132+ let meta_sized = collect_bounds ( hir_bounds, context , meta_sized_did) ;
134133
135134 let pointee_sized_did = tcx. require_lang_item ( hir:: LangItem :: PointeeSized , span) ;
136- let pointee_sized = collect_bounds ( hir_bounds, self_ty_where_predicates , pointee_sized_did) ;
135+ let pointee_sized = collect_bounds ( hir_bounds, context , pointee_sized_did) ;
137136
138137 CollectedSizednessBounds { sized, meta_sized, pointee_sized }
139138}
@@ -161,13 +160,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
161160 /// bounds are present.
162161 /// - On parameters, opaque type, associated types and trait aliases, add a `MetaSized` bound if
163162 /// a `?Sized` bound is present.
164- pub ( crate ) fn add_sizedness_bounds (
163+ pub ( crate ) fn add_implicit_sizedness_bounds (
165164 & self ,
166165 bounds : & mut Vec < ( ty:: Clause < ' tcx > , Span ) > ,
167166 self_ty : Ty < ' tcx > ,
168167 hir_bounds : & ' tcx [ hir:: GenericBound < ' tcx > ] ,
169- self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir:: WherePredicate < ' tcx > ] ) > ,
170- trait_did : Option < LocalDefId > ,
168+ context : ImpliedBoundsContext < ' tcx > ,
171169 span : Span ,
172170 ) {
173171 let tcx = self . tcx ( ) ;
@@ -181,33 +179,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
181179 let pointee_sized_did = tcx. require_lang_item ( hir:: LangItem :: PointeeSized , span) ;
182180
183181 // If adding sizedness bounds to a trait, then there are some relevant early exits
184- if let Some ( trait_did) = trait_did {
185- let trait_did = trait_did. to_def_id ( ) ;
186- // Never add a default supertrait to `PointeeSized`.
187- if trait_did == pointee_sized_did {
188- return ;
182+ match context {
183+ ImpliedBoundsContext :: TraitDef ( trait_did) => {
184+ let trait_did = trait_did. to_def_id ( ) ;
185+ // Never add a default supertrait to `PointeeSized`.
186+ if trait_did == pointee_sized_did {
187+ return ;
188+ }
189+ // Don't add default sizedness supertraits to auto traits because it isn't possible to
190+ // relax an automatically added supertrait on the defn itself.
191+ if tcx. trait_is_auto ( trait_did) {
192+ return ;
193+ }
189194 }
190- // Don't add default sizedness supertraits to auto traits because it isn't possible to
191- // relax an automatically added supertrait on the defn itself.
192- if tcx. trait_is_auto ( trait_did) {
193- return ;
195+ ImpliedBoundsContext :: TyParam ( ..) | ImpliedBoundsContext :: AssociatedTypeOrImplTrait => {
196+ // Report invalid relaxed bounds.
197+ // FIXME: Since we only call this validation function here in this function, we only
198+ // fully validate relaxed bounds in contexts where we perform
199+ // "sized elaboration". In most cases that doesn't matter because we *usually*
200+ // reject such relaxed bounds outright during AST lowering.
201+ // However, this can easily get out of sync! Ideally, we would perform this step
202+ // where we are guaranteed to catch *all* bounds like in
203+ // `Self::lower_poly_trait_ref`. List of concrete issues:
204+ // FIXME(more_maybe_bounds): We don't call this for trait object tys, supertrait
205+ // bounds, trait alias bounds, assoc type bounds (ATB)!
206+ let bounds = collect_relaxed_bounds ( hir_bounds, context) ;
207+ self . reject_duplicate_relaxed_bounds ( bounds) ;
194208 }
195- } else {
196- // Report invalid relaxed bounds.
197- // FIXME: Since we only call this validation function here in this function, we only
198- // fully validate relaxed bounds in contexts where we perform
199- // "sized elaboration". In most cases that doesn't matter because we *usually*
200- // reject such relaxed bounds outright during AST lowering.
201- // However, this can easily get out of sync! Ideally, we would perform this step
202- // where we are guaranteed to catch *all* bounds like in
203- // `Self::lower_poly_trait_ref`. List of concrete issues:
204- // FIXME(more_maybe_bounds): We don't call this for trait object tys, supertrait
205- // bounds, trait alias bounds, assoc type bounds (ATB)!
206- let bounds = collect_relaxed_bounds ( hir_bounds, self_ty_where_predicates) ;
207- self . reject_duplicate_relaxed_bounds ( bounds) ;
208209 }
209210
210- let collected = collect_sizedness_bounds ( tcx, hir_bounds, self_ty_where_predicates , span) ;
211+ let collected = collect_sizedness_bounds ( tcx, hir_bounds, context , span) ;
211212 if ( collected. sized . maybe || collected. sized . negative )
212213 && !collected. sized . positive
213214 && !collected. meta_sized . any ( )
@@ -217,15 +218,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
217218 // other explicit ones) - this can happen for trait aliases as well as bounds.
218219 add_trait_bound ( tcx, bounds, self_ty, meta_sized_did, span) ;
219220 } else if !collected. any ( ) {
220- if trait_did. is_some ( ) {
221- // If there are no explicit sizedness bounds on a trait then add a default
222- // `MetaSized` supertrait.
223- add_trait_bound ( tcx, bounds, self_ty, meta_sized_did, span) ;
224- } else {
225- // If there are no explicit sizedness bounds on a parameter then add a default
226- // `Sized` bound.
227- let sized_did = tcx. require_lang_item ( hir:: LangItem :: Sized , span) ;
228- add_trait_bound ( tcx, bounds, self_ty, sized_did, span) ;
221+ match context {
222+ ImpliedBoundsContext :: TraitDef ( ..) => {
223+ // If there are no explicit sizedness bounds on a trait then add a default
224+ // `MetaSized` supertrait.
225+ add_trait_bound ( tcx, bounds, self_ty, meta_sized_did, span) ;
226+ }
227+ ImpliedBoundsContext :: TyParam ( ..)
228+ | ImpliedBoundsContext :: AssociatedTypeOrImplTrait => {
229+ // If there are no explicit sizedness bounds on a parameter then add a default
230+ // `Sized` bound.
231+ let sized_did = tcx. require_lang_item ( hir:: LangItem :: Sized , span) ;
232+ add_trait_bound ( tcx, bounds, self_ty, sized_did, span) ;
233+ }
229234 }
230235 }
231236 }
@@ -251,7 +256,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
251256 bounds,
252257 self . tcx ( ) . types . self_param ,
253258 hir_bounds,
254- Some ( ( trait_def_id, hir_generics. predicates ) ) ,
259+ ImpliedBoundsContext :: TyParam ( trait_def_id, hir_generics. predicates ) ,
255260 span,
256261 ) ;
257262 }
@@ -261,18 +266,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
261266 bounds : & mut Vec < ( ty:: Clause < ' tcx > , Span ) > ,
262267 self_ty : Ty < ' tcx > ,
263268 hir_bounds : & [ hir:: GenericBound < ' tcx > ] ,
264- self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir :: WherePredicate < ' tcx > ] ) > ,
269+ context : ImpliedBoundsContext < ' tcx > ,
265270 span : Span ,
266271 ) {
267272 self . tcx ( ) . default_traits ( ) . iter ( ) . for_each ( |default_trait| {
268- self . add_default_trait (
269- * default_trait,
270- bounds,
271- self_ty,
272- hir_bounds,
273- self_ty_where_predicates,
274- span,
275- ) ;
273+ self . add_default_trait ( * default_trait, bounds, self_ty, hir_bounds, context, span) ;
276274 } ) ;
277275 }
278276
@@ -285,13 +283,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
285283 bounds : & mut Vec < ( ty:: Clause < ' tcx > , Span ) > ,
286284 self_ty : Ty < ' tcx > ,
287285 hir_bounds : & [ hir:: GenericBound < ' tcx > ] ,
288- self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir :: WherePredicate < ' tcx > ] ) > ,
286+ context : ImpliedBoundsContext < ' tcx > ,
289287 span : Span ,
290288 ) {
291289 let tcx = self . tcx ( ) ;
292290 let trait_id = tcx. lang_items ( ) . get ( trait_) ;
293291 if let Some ( trait_id) = trait_id
294- && self . should_add_default_traits ( trait_id, hir_bounds, self_ty_where_predicates )
292+ && self . should_add_default_traits ( trait_id, hir_bounds, context )
295293 {
296294 add_trait_bound ( tcx, bounds, self_ty, trait_id, span) ;
297295 }
@@ -302,9 +300,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
302300 & self ,
303301 trait_def_id : DefId ,
304302 hir_bounds : & ' a [ hir:: GenericBound < ' tcx > ] ,
305- self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir :: WherePredicate < ' tcx > ] ) > ,
303+ context : ImpliedBoundsContext < ' tcx > ,
306304 ) -> bool {
307- let collected = collect_bounds ( hir_bounds, self_ty_where_predicates , trait_def_id) ;
305+ let collected = collect_bounds ( hir_bounds, context , trait_def_id) ;
308306 !self . tcx ( ) . has_attr ( CRATE_DEF_ID , sym:: rustc_no_implicit_bounds) && !collected. any ( )
309307 }
310308
0 commit comments