@@ -25,18 +25,19 @@ use crate::hir_ty_lowering::{
2525
2626#[ derive( Debug , Default ) ]
2727struct CollectedBound {
28+ constness : bool ,
2829 /// `Trait`
29- positive : bool ,
30+ positive : Option < Span > ,
3031 /// `?Trait`
31- maybe : bool ,
32+ maybe : Option < Span > ,
3233 /// `!Trait`
33- negative : bool ,
34+ negative : Option < Span > ,
3435}
3536
3637impl CollectedBound {
3738 /// Returns `true` if any of `Trait`, `?Trait` or `!Trait` were encountered.
3839 fn any ( & self ) -> bool {
39- self . positive || self . maybe || self . negative
40+ self . positive . is_some ( ) || self . maybe . is_some ( ) || self . negative . is_some ( )
4041 }
4142}
4243
@@ -61,15 +62,15 @@ impl CollectedSizednessBounds {
6162fn search_bounds_for < ' tcx > (
6263 hir_bounds : & ' tcx [ hir:: GenericBound < ' tcx > ] ,
6364 self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir:: WherePredicate < ' tcx > ] ) > ,
64- mut f : impl FnMut ( & ' tcx PolyTraitRef < ' tcx > ) ,
65+ mut f : impl FnMut ( & ' tcx PolyTraitRef < ' tcx > , Span ) ,
6566) {
6667 let mut search_bounds = |hir_bounds : & ' tcx [ hir:: GenericBound < ' tcx > ] | {
6768 for hir_bound in hir_bounds {
6869 let hir:: GenericBound :: Trait ( ptr) = hir_bound else {
6970 continue ;
7071 } ;
7172
72- f ( ptr)
73+ f ( ptr, hir_bound . span ( ) )
7374 }
7475 } ;
7576
@@ -90,7 +91,7 @@ fn collect_unbounds<'tcx>(
9091 self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir:: WherePredicate < ' tcx > ] ) > ,
9192) -> SmallVec < [ & ' tcx PolyTraitRef < ' tcx > ; 1 ] > {
9293 let mut unbounds: SmallVec < [ _ ; 1 ] > = SmallVec :: new ( ) ;
93- search_bounds_for ( hir_bounds, self_ty_where_predicates, |ptr| {
94+ search_bounds_for ( hir_bounds, self_ty_where_predicates, |ptr, _ | {
9495 if matches ! ( ptr. modifiers. polarity, hir:: BoundPolarity :: Maybe ( _) ) {
9596 unbounds. push ( ptr) ;
9697 }
@@ -104,15 +105,20 @@ fn collect_bounds<'a, 'tcx>(
104105 target_did : DefId ,
105106) -> CollectedBound {
106107 let mut collect_into = CollectedBound :: default ( ) ;
107- search_bounds_for ( hir_bounds, self_ty_where_predicates, |ptr| {
108+ search_bounds_for ( hir_bounds, self_ty_where_predicates, |ptr, span | {
108109 if !matches ! ( ptr. trait_ref. path. res, Res :: Def ( DefKind :: Trait , did) if did == target_did) {
109110 return ;
110111 }
111112
113+ collect_into. constness = matches ! (
114+ ptr. modifiers. constness,
115+ hir:: BoundConstness :: Always ( _) | hir:: BoundConstness :: Maybe ( _)
116+ ) ;
117+
112118 match ptr. modifiers . polarity {
113- hir:: BoundPolarity :: Maybe ( _) => collect_into. maybe = true ,
114- hir:: BoundPolarity :: Negative ( _) => collect_into. negative = true ,
115- hir:: BoundPolarity :: Positive => collect_into. positive = true ,
119+ hir:: BoundPolarity :: Maybe ( _) => collect_into. maybe = Some ( span ) ,
120+ hir:: BoundPolarity :: Negative ( _) => collect_into. negative = Some ( span ) ,
121+ hir:: BoundPolarity :: Positive => collect_into. positive = Some ( span ) ,
116122 }
117123 } ) ;
118124 collect_into
@@ -215,9 +221,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
215221 let tcx = self . tcx ( ) ;
216222
217223 let span = tcx. def_span ( trait_did) ;
224+ let sized_did = tcx. require_lang_item ( LangItem :: Sized , Some ( span) ) ;
218225 let meta_sized_did = tcx. require_lang_item ( LangItem :: MetaSized , Some ( span) ) ;
219226 let pointee_sized_did = tcx. require_lang_item ( LangItem :: PointeeSized , Some ( span) ) ;
220227
228+ let trait_hir_id = tcx. local_def_id_to_hir_id ( trait_did) ;
221229 let trait_did = trait_did. to_def_id ( ) ;
222230 if trait_did == pointee_sized_did {
223231 // Never add a default supertrait to `PointeeSized`.
@@ -230,11 +238,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
230238 }
231239
232240 let collected = collect_sizedness_bounds ( tcx, hir_bounds, None , span) ;
233- if !collected. any ( ) && trait_did != pointee_sized_did {
234- // If there are no explicit sizedness bounds then add a default `const MetaSized`
235- // supertrait.
241+ if !collected. any ( ) && !tcx. sess . edition ( ) . at_least_edition_future ( ) {
242+ // Emit migration lint when the feature is enabled.
243+ self . emit_implicit_const_meta_sized_supertrait_lint ( trait_hir_id, span) ;
244+
245+ // If it is not Edition Future and there are no explicit sizedness bounds then add a
246+ // default `const MetaSized` supertrait.
236247 add_trait_predicate ( tcx, bounds, self_ty, meta_sized_did, span) ;
237248 add_host_effect_predicate ( tcx, filter, bounds, self_ty, meta_sized_did, span) ;
249+ } else if let Some ( bound_span) = collected. sized . positive
250+ && !collected. sized . constness
251+ && !tcx. sess . edition ( ) . at_least_edition_future ( )
252+ {
253+ // Emit migration lint when the feature is enabled.
254+ self . emit_sized_to_const_sized_lint ( trait_hir_id, bound_span) ;
255+
256+ // If it is not Edition Future then `Sized` is equivalent to writing `const Sized`.
257+ add_trait_predicate ( tcx, bounds, self_ty, sized_did, bound_span) ;
258+ add_host_effect_predicate ( tcx, filter, bounds, self_ty, sized_did, bound_span) ;
238259 }
239260
240261 // See doc comment on `adjust_sizedness_predicates`.
@@ -251,6 +272,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
251272 hir_bounds : & ' tcx [ hir:: GenericBound < ' tcx > ] ,
252273 self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir:: WherePredicate < ' tcx > ] ) > ,
253274 span : Span ,
275+ trait_did : LocalDefId ,
254276 filter : PredicateFilter ,
255277 ) {
256278 let tcx = self . tcx ( ) ;
@@ -260,23 +282,39 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
260282 let pointee_sized_did = tcx. require_lang_item ( LangItem :: PointeeSized , Some ( span) ) ;
261283
262284 // Report invalid unbounds.
285+ let trait_hir_id = tcx. local_def_id_to_hir_id ( trait_did) ;
263286 let unbounds = collect_unbounds ( hir_bounds, self_ty_where_predicates) ;
264- self . check_and_report_invalid_unbounds_on_param ( unbounds) ;
287+ self . check_and_report_invalid_unbounds_on_param ( trait_hir_id , unbounds) ;
265288
266289 let collected = collect_sizedness_bounds ( tcx, hir_bounds, self_ty_where_predicates, span) ;
267- if ( collected. sized . maybe || collected. sized . negative )
268- && !collected. sized . positive
290+ if ( collected. sized . maybe . is_some ( ) || collected. sized . negative . is_some ( ) )
291+ && !collected. sized . positive . is_some ( )
269292 && !collected. meta_sized . any ( )
270293 && !collected. pointee_sized . any ( )
271294 {
272295 // `?Sized` is equivalent to `const MetaSized` (but only add the bound if there aren't
273296 // any other explicit ones)
274297 add_trait_predicate ( tcx, bounds, self_ty, meta_sized_did, span) ;
275298 add_host_effect_predicate ( tcx, filter, bounds, self_ty, meta_sized_did, span) ;
299+ } else if let Some ( bound_span) = collected. sized . positive
300+ && !collected. sized . constness
301+ && !tcx. sess . edition ( ) . at_least_edition_future ( )
302+ {
303+ // Emit migration lint when the feature is enabled.
304+ self . emit_sized_to_const_sized_lint ( trait_hir_id, bound_span) ;
305+
306+ // Replace `Sized` with `const Sized`.
307+ add_trait_predicate ( tcx, bounds, self_ty, sized_did, bound_span) ;
308+ add_host_effect_predicate ( tcx, filter, bounds, self_ty, sized_did, bound_span) ;
276309 } else if !collected. any ( ) {
277310 // If there are no explicit sizedness bounds then add a default `const Sized` bound.
278311 add_trait_predicate ( tcx, bounds, self_ty, sized_did, span) ;
279- add_host_effect_predicate ( tcx, filter, bounds, self_ty, sized_did, span) ;
312+
313+ if !tcx. sess . edition ( ) . at_least_edition_future ( ) {
314+ self . emit_default_sized_to_const_sized_lint ( trait_hir_id, span) ;
315+
316+ add_host_effect_predicate ( tcx, filter, bounds, self_ty, sized_did, span) ;
317+ }
280318 }
281319
282320 // See doc comment on `adjust_sizedness_predicates`.
@@ -476,7 +514,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
476514 self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir:: WherePredicate < ' tcx > ] ) > ,
477515 ) -> bool {
478516 let collected = collect_bounds ( hir_bounds, self_ty_where_predicates, trait_def_id) ;
479- !( collected. positive || collected. maybe || collected. negative )
517+ !( collected. positive . is_some ( ) || collected. maybe . is_some ( ) || collected. negative . is_some ( ) )
480518 }
481519
482520 /// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any.
0 commit comments