@@ -25,18 +25,19 @@ use crate::hir_ty_lowering::{
25
25
26
26
#[ derive( Debug , Default ) ]
27
27
struct CollectedBound {
28
+ constness : bool ,
28
29
/// `Trait`
29
- positive : bool ,
30
+ positive : Option < Span > ,
30
31
/// `?Trait`
31
- maybe : bool ,
32
+ maybe : Option < Span > ,
32
33
/// `!Trait`
33
- negative : bool ,
34
+ negative : Option < Span > ,
34
35
}
35
36
36
37
impl CollectedBound {
37
38
/// Returns `true` if any of `Trait`, `?Trait` or `!Trait` were encountered.
38
39
fn any ( & self ) -> bool {
39
- self . positive || self . maybe || self . negative
40
+ self . positive . is_some ( ) || self . maybe . is_some ( ) || self . negative . is_some ( )
40
41
}
41
42
}
42
43
@@ -61,15 +62,15 @@ impl CollectedSizednessBounds {
61
62
fn search_bounds_for < ' tcx > (
62
63
hir_bounds : & ' tcx [ hir:: GenericBound < ' tcx > ] ,
63
64
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 ) ,
65
66
) {
66
67
let mut search_bounds = |hir_bounds : & ' tcx [ hir:: GenericBound < ' tcx > ] | {
67
68
for hir_bound in hir_bounds {
68
69
let hir:: GenericBound :: Trait ( ptr) = hir_bound else {
69
70
continue ;
70
71
} ;
71
72
72
- f ( ptr)
73
+ f ( ptr, hir_bound . span ( ) )
73
74
}
74
75
} ;
75
76
@@ -90,7 +91,7 @@ fn collect_unbounds<'tcx>(
90
91
self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir:: WherePredicate < ' tcx > ] ) > ,
91
92
) -> SmallVec < [ & ' tcx PolyTraitRef < ' tcx > ; 1 ] > {
92
93
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, _ | {
94
95
if matches ! ( ptr. modifiers. polarity, hir:: BoundPolarity :: Maybe ( _) ) {
95
96
unbounds. push ( ptr) ;
96
97
}
@@ -104,15 +105,20 @@ fn collect_bounds<'a, 'tcx>(
104
105
target_did : DefId ,
105
106
) -> CollectedBound {
106
107
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 | {
108
109
if !matches ! ( ptr. trait_ref. path. res, Res :: Def ( DefKind :: Trait , did) if did == target_did) {
109
110
return ;
110
111
}
111
112
113
+ collect_into. constness = matches ! (
114
+ ptr. modifiers. constness,
115
+ hir:: BoundConstness :: Always ( _) | hir:: BoundConstness :: Maybe ( _)
116
+ ) ;
117
+
112
118
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 ) ,
116
122
}
117
123
} ) ;
118
124
collect_into
@@ -215,9 +221,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
215
221
let tcx = self . tcx ( ) ;
216
222
217
223
let span = tcx. def_span ( trait_did) ;
224
+ let sized_did = tcx. require_lang_item ( LangItem :: Sized , Some ( span) ) ;
218
225
let meta_sized_did = tcx. require_lang_item ( LangItem :: MetaSized , Some ( span) ) ;
219
226
let pointee_sized_did = tcx. require_lang_item ( LangItem :: PointeeSized , Some ( span) ) ;
220
227
228
+ let trait_hir_id = tcx. local_def_id_to_hir_id ( trait_did) ;
221
229
let trait_did = trait_did. to_def_id ( ) ;
222
230
if trait_did == pointee_sized_did {
223
231
// Never add a default supertrait to `PointeeSized`.
@@ -230,11 +238,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
230
238
}
231
239
232
240
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.
236
247
add_trait_predicate ( tcx, bounds, self_ty, meta_sized_did, span) ;
237
248
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) ;
238
259
}
239
260
240
261
// See doc comment on `adjust_sizedness_predicates`.
@@ -251,6 +272,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
251
272
hir_bounds : & ' tcx [ hir:: GenericBound < ' tcx > ] ,
252
273
self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir:: WherePredicate < ' tcx > ] ) > ,
253
274
span : Span ,
275
+ trait_did : LocalDefId ,
254
276
filter : PredicateFilter ,
255
277
) {
256
278
let tcx = self . tcx ( ) ;
@@ -260,23 +282,39 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
260
282
let pointee_sized_did = tcx. require_lang_item ( LangItem :: PointeeSized , Some ( span) ) ;
261
283
262
284
// Report invalid unbounds.
285
+ let trait_hir_id = tcx. local_def_id_to_hir_id ( trait_did) ;
263
286
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) ;
265
288
266
289
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 ( )
269
292
&& !collected. meta_sized . any ( )
270
293
&& !collected. pointee_sized . any ( )
271
294
{
272
295
// `?Sized` is equivalent to `const MetaSized` (but only add the bound if there aren't
273
296
// any other explicit ones)
274
297
add_trait_predicate ( tcx, bounds, self_ty, meta_sized_did, span) ;
275
298
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) ;
276
309
} else if !collected. any ( ) {
277
310
// If there are no explicit sizedness bounds then add a default `const Sized` bound.
278
311
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
+ }
280
318
}
281
319
282
320
// See doc comment on `adjust_sizedness_predicates`.
@@ -476,7 +514,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
476
514
self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir:: WherePredicate < ' tcx > ] ) > ,
477
515
) -> bool {
478
516
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 ( ) )
480
518
}
481
519
482
520
/// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any.
0 commit comments