@@ -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
@@ -84,17 +85,23 @@ fn collect_sizedness_bounds<'tcx>(
84
85
unbounds. push ( ptr) ;
85
86
}
86
87
88
+ let has_constness = matches ! (
89
+ ptr. modifiers. constness,
90
+ hir:: BoundConstness :: Always ( _) | hir:: BoundConstness :: Maybe ( _)
91
+ ) ;
92
+
87
93
let collect_into = match ptr. trait_ref . path . res {
88
94
Res :: Def ( DefKind :: Trait , did) if did == sized_did => & mut sized,
89
95
Res :: Def ( DefKind :: Trait , did) if did == meta_sized_did => & mut meta_sized,
90
96
Res :: Def ( DefKind :: Trait , did) if did == pointee_sized_did => & mut pointee_sized,
91
97
_ => continue ,
92
98
} ;
93
99
100
+ collect_into. constness = has_constness;
94
101
match ptr. modifiers . polarity {
95
- hir:: BoundPolarity :: Maybe ( _) => collect_into. maybe = true ,
96
- hir:: BoundPolarity :: Negative ( _) => collect_into. negative = true ,
97
- hir:: BoundPolarity :: Positive => collect_into. positive = true ,
102
+ hir:: BoundPolarity :: Maybe ( _) => collect_into. maybe = Some ( hir_bound . span ( ) ) ,
103
+ hir:: BoundPolarity :: Negative ( _) => collect_into. negative = Some ( hir_bound . span ( ) ) ,
104
+ hir:: BoundPolarity :: Positive => collect_into. positive = Some ( hir_bound . span ( ) ) ,
98
105
}
99
106
}
100
107
} ;
@@ -183,21 +190,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
183
190
let tcx = self . tcx ( ) ;
184
191
185
192
let span = tcx. def_span ( trait_did) ;
193
+ let sized_did = tcx. require_lang_item ( LangItem :: Sized , Some ( span) ) ;
186
194
let meta_sized_did = tcx. require_lang_item ( LangItem :: MetaSized , Some ( span) ) ;
187
195
let pointee_sized_did = tcx. require_lang_item ( LangItem :: PointeeSized , Some ( span) ) ;
188
196
197
+ let trait_hir_id = tcx. local_def_id_to_hir_id ( trait_did) ;
189
198
let trait_did = trait_did. to_def_id ( ) ;
190
199
if trait_did == pointee_sized_did {
191
200
// Never add a default supertrait to `PointeeSized`.
192
201
return ;
193
202
}
194
203
195
204
let ( collected, _unbounds) = collect_sizedness_bounds ( tcx, hir_bounds, None , span) ;
196
- if !collected. any ( ) && trait_did != pointee_sized_did {
197
- // If there are no explicit sizedness bounds then add a default `const MetaSized`
198
- // supertrait.
205
+ if !collected. any ( ) && !tcx. sess . edition ( ) . at_least_edition_future ( ) {
206
+ // Emit migration lint when the feature is enabled.
207
+ self . emit_implicit_const_meta_sized_supertrait_lint ( trait_hir_id, span) ;
208
+
209
+ // If it is not Edition Future and there are no explicit sizedness bounds then add a
210
+ // default `const MetaSized` supertrait.
199
211
add_trait_predicate ( tcx, bounds, self_ty, meta_sized_did, span) ;
200
212
add_host_effect_predicate ( tcx, bounds, self_ty, meta_sized_did, span) ;
213
+ } else if let Some ( bound_span) = collected. sized . positive
214
+ && !collected. sized . constness
215
+ && !tcx. sess . edition ( ) . at_least_edition_future ( )
216
+ {
217
+ // Emit migration lint when the feature is enabled.
218
+ self . emit_sized_to_const_sized_lint ( trait_hir_id, bound_span) ;
219
+
220
+ // If it is not Edition Future then `Sized` is equivalent to writing `const Sized`.
221
+ add_trait_predicate ( tcx, bounds, self_ty, sized_did, bound_span) ;
222
+ add_host_effect_predicate ( tcx, bounds, self_ty, sized_did, bound_span) ;
201
223
}
202
224
203
225
// See doc comment on `adjust_sizedness_predicates`.
@@ -214,6 +236,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
214
236
hir_bounds : & ' tcx [ hir:: GenericBound < ' tcx > ] ,
215
237
self_ty_where_predicates : Option < ( LocalDefId , & ' tcx [ hir:: WherePredicate < ' tcx > ] ) > ,
216
238
span : Span ,
239
+ trait_did : LocalDefId ,
217
240
) {
218
241
let tcx = self . tcx ( ) ;
219
242
@@ -223,21 +246,37 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
223
246
224
247
let ( collected, unbounds) =
225
248
collect_sizedness_bounds ( tcx, hir_bounds, self_ty_where_predicates, span) ;
226
- self . check_and_report_invalid_unbounds_on_param ( unbounds) ;
249
+ let trait_hir_id = tcx. local_def_id_to_hir_id ( trait_did) ;
250
+ self . check_and_report_invalid_unbounds_on_param ( trait_hir_id, unbounds) ;
227
251
228
- if ( collected. sized . maybe || collected. sized . negative )
229
- && !collected. sized . positive
252
+ if ( collected. sized . maybe . is_some ( ) || collected. sized . negative . is_some ( ) )
253
+ && !collected. sized . positive . is_some ( )
230
254
&& !collected. meta_sized . any ( )
231
255
&& !collected. pointee_sized . any ( )
232
256
{
233
257
// `?Sized` is equivalent to `const MetaSized` (but only add the bound if there aren't
234
258
// any other explicit ones)
235
259
add_trait_predicate ( tcx, bounds, self_ty, meta_sized_did, span) ;
236
260
add_host_effect_predicate ( tcx, bounds, self_ty, meta_sized_did, span) ;
261
+ } else if let Some ( bound_span) = collected. sized . positive
262
+ && !collected. sized . constness
263
+ && !tcx. sess . edition ( ) . at_least_edition_future ( )
264
+ {
265
+ // Emit migration lint when the feature is enabled.
266
+ self . emit_sized_to_const_sized_lint ( trait_hir_id, bound_span) ;
267
+
268
+ // Replace `Sized` with `const Sized`.
269
+ add_trait_predicate ( tcx, bounds, self_ty, sized_did, bound_span) ;
270
+ add_host_effect_predicate ( tcx, bounds, self_ty, sized_did, bound_span) ;
237
271
} else if !collected. any ( ) {
238
272
// If there are no explicit sizedness bounds then add a default `const Sized` bound.
239
273
add_trait_predicate ( tcx, bounds, self_ty, sized_did, span) ;
240
- add_host_effect_predicate ( tcx, bounds, self_ty, sized_did, span) ;
274
+
275
+ if !tcx. sess . edition ( ) . at_least_edition_future ( ) {
276
+ self . emit_default_sized_to_const_sized_lint ( trait_hir_id, span) ;
277
+
278
+ add_host_effect_predicate ( tcx, bounds, self_ty, sized_did, span) ;
279
+ }
241
280
}
242
281
243
282
// See doc comment on `adjust_sizedness_predicates`.
0 commit comments