@@ -15,6 +15,7 @@ use rustc_ast::{
15
15
FormatArgPosition , FormatArgPositionKind , FormatArgsPiece , FormatArgumentKind , FormatCount , FormatOptions ,
16
16
FormatPlaceholder , FormatTrait ,
17
17
} ;
18
+ use rustc_attr_parsing:: RustcVersion ;
18
19
use rustc_data_structures:: fx:: FxHashMap ;
19
20
use rustc_errors:: Applicability ;
20
21
use rustc_errors:: SuggestionStyle :: { CompletelyHidden , ShowCode } ;
@@ -206,17 +207,17 @@ pub struct FormatArgs<'tcx> {
206
207
format_args : FormatArgsStorage ,
207
208
msrv : Msrv ,
208
209
ignore_mixed : bool ,
209
- ty_feature_map : FxHashMap < Ty < ' tcx > , Option < Symbol > > ,
210
+ ty_msrv_map : FxHashMap < Ty < ' tcx > , Option < RustcVersion > > ,
210
211
}
211
212
212
213
impl < ' tcx > FormatArgs < ' tcx > {
213
214
pub fn new ( tcx : TyCtxt < ' tcx > , conf : & ' static Conf , format_args : FormatArgsStorage ) -> Self {
214
- let ty_feature_map = make_ty_feature_map ( tcx) ;
215
+ let ty_msrv_map = make_ty_msrv_map ( tcx) ;
215
216
Self {
216
217
format_args,
217
218
msrv : conf. msrv . clone ( ) ,
218
219
ignore_mixed : conf. allow_mixed_uninlined_format_args ,
219
- ty_feature_map ,
220
+ ty_msrv_map ,
220
221
}
221
222
}
222
223
}
@@ -233,7 +234,8 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs<'tcx> {
233
234
macro_call : & macro_call,
234
235
format_args,
235
236
ignore_mixed : self . ignore_mixed ,
236
- ty_feature_map : & self . ty_feature_map ,
237
+ msrv : & self . msrv ,
238
+ ty_msrv_map : & self . ty_msrv_map ,
237
239
} ;
238
240
239
241
linter. check_templates ( ) ;
@@ -253,7 +255,8 @@ struct FormatArgsExpr<'a, 'tcx> {
253
255
macro_call : & ' a MacroCall ,
254
256
format_args : & ' a rustc_ast:: FormatArgs ,
255
257
ignore_mixed : bool ,
256
- ty_feature_map : & ' a FxHashMap < Ty < ' tcx > , Option < Symbol > > ,
258
+ msrv : & ' a Msrv ,
259
+ ty_msrv_map : & ' a FxHashMap < Ty < ' tcx > , Option < RustcVersion > > ,
257
260
}
258
261
259
262
impl < ' tcx > FormatArgsExpr < ' _ , ' tcx > {
@@ -538,19 +541,19 @@ impl<'tcx> FormatArgsExpr<'_, 'tcx> {
538
541
fn can_display_format ( & self , ty : Ty < ' tcx > ) -> bool {
539
542
let ty = ty. peel_refs ( ) ;
540
543
541
- if let Some ( feature ) = self . ty_feature_map . get ( & ty)
542
- && feature . is_none_or ( |feature | self . cx . tcx . features ( ) . enabled ( feature ) )
544
+ if let Some ( msrv ) = self . ty_msrv_map . get ( & ty)
545
+ && msrv . is_none_or ( |msrv | self . msrv . meets ( msrv ) )
543
546
{
544
547
return true ;
545
548
}
546
549
547
- // Even if `ty` is not in `self.ty_feature_map `, check whether `ty` implements `Deref` with
548
- // a `Target` that is in `self.ty_feature_map `.
550
+ // Even if `ty` is not in `self.ty_msrv_map `, check whether `ty` implements `Deref` with
551
+ // a `Target` that is in `self.ty_msrv_map `.
549
552
if let Some ( deref_trait_id) = self . cx . tcx . lang_items ( ) . deref_trait ( )
550
553
&& implements_trait ( self . cx , ty, deref_trait_id, & [ ] )
551
554
&& let Some ( target_ty) = self . cx . get_associated_type ( ty, deref_trait_id, "Target" )
552
- && let Some ( feature ) = self . ty_feature_map . get ( & target_ty)
553
- && feature . is_none_or ( |feature | self . cx . tcx . features ( ) . enabled ( feature ) )
555
+ && let Some ( msrv ) = self . ty_msrv_map . get ( & target_ty)
556
+ && msrv . is_none_or ( |msrv | self . msrv . meets ( msrv ) )
554
557
{
555
558
return true ;
556
559
}
@@ -559,8 +562,8 @@ impl<'tcx> FormatArgsExpr<'_, 'tcx> {
559
562
}
560
563
}
561
564
562
- fn make_ty_feature_map ( tcx : TyCtxt < ' _ > ) -> FxHashMap < Ty < ' _ > , Option < Symbol > > {
563
- [ ( sym:: OsStr , Some ( Symbol :: intern ( "os_str_display" ) ) ) , ( sym:: Path , None ) ]
565
+ fn make_ty_msrv_map ( tcx : TyCtxt < ' _ > ) -> FxHashMap < Ty < ' _ > , Option < RustcVersion > > {
566
+ [ ( sym:: OsStr , Some ( msrvs :: OS_STR_DISPLAY ) ) , ( sym:: Path , None ) ]
564
567
. into_iter ( )
565
568
. filter_map ( |( name, feature) | {
566
569
tcx. get_diagnostic_item ( name) . map ( |def_id| {
0 commit comments