@@ -21,7 +21,7 @@ pub mod generics;
2121
2222use std:: slice;
2323
24- use rustc_ast:: LitKind ;
24+ use rustc_ast:: { LitFloatType , LitIntType , LitKind } ;
2525use rustc_data_structures:: assert_matches;
2626use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap , FxIndexSet } ;
2727use rustc_errors:: codes:: * ;
@@ -31,7 +31,7 @@ use rustc_errors::{
3131use rustc_hir:: attrs:: AttributeKind ;
3232use rustc_hir:: def:: { CtorKind , CtorOf , DefKind , Res } ;
3333use rustc_hir:: def_id:: { DefId , LocalDefId } ;
34- use rustc_hir:: { self as hir, AnonConst , GenericArg , GenericArgs , HirId , find_attr} ;
34+ use rustc_hir:: { self as hir, AnonConst , GenericArg , GenericArgs , HirId , LangItem , find_attr} ;
3535use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
3636use rustc_infer:: traits:: DynCompatibilityViolation ;
3737use rustc_macros:: { TypeFoldable , TypeVisitable } ;
@@ -2807,10 +2807,70 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
28072807 #[ instrument( skip( self ) , level = "debug" ) ]
28082808 fn lower_const_arg_literal ( & self , kind : & LitKind , ty : Ty < ' tcx > , span : Span ) -> Const < ' tcx > {
28092809 let tcx = self . tcx ( ) ;
2810+ if let LitKind :: Err ( guar) = * kind {
2811+ return ty:: Const :: new_error ( tcx, guar) ;
2812+ }
2813+ if !self . const_lit_matches_ty ( kind, ty, false ) {
2814+ let found = self . const_lit_description ( kind) ;
2815+ let e = tcx. dcx ( ) . span_err ( span, format ! ( "expected `{}`, found `{found}`" , ty) ) ;
2816+ return ty:: Const :: new_error ( tcx, e) ;
2817+ }
28102818 let input = LitToConstInput { lit : * kind, ty, neg : false } ;
28112819 tcx. at ( span) . lit_to_const ( input)
28122820 }
28132821
2822+ fn const_lit_matches_ty ( & self , kind : & LitKind , ty : Ty < ' tcx > , neg : bool ) -> bool {
2823+ let tcx = self . tcx ( ) ;
2824+ match ( * kind, ty. kind ( ) ) {
2825+ ( LitKind :: Str ( ..) , ty:: Ref ( _, inner_ty, _) ) if inner_ty. is_str ( ) => true ,
2826+ ( LitKind :: Str ( ..) , ty:: Str ) if tcx. features ( ) . deref_patterns ( ) => true ,
2827+ ( LitKind :: ByteStr ( ..) , ty:: Ref ( _, inner_ty, _) )
2828+ if let ty:: Slice ( ty) | ty:: Array ( ty, _) = inner_ty. kind ( )
2829+ && matches ! ( ty. kind( ) , ty:: Uint ( ty:: UintTy :: U8 ) ) =>
2830+ {
2831+ true
2832+ }
2833+ ( LitKind :: ByteStr ( ..) , ty:: Slice ( inner_ty) | ty:: Array ( inner_ty, _) )
2834+ if tcx. features ( ) . deref_patterns ( )
2835+ && matches ! ( inner_ty. kind( ) , ty:: Uint ( ty:: UintTy :: U8 ) ) =>
2836+ {
2837+ true
2838+ }
2839+ ( LitKind :: Byte ( ..) , ty:: Uint ( ty:: UintTy :: U8 ) ) => true ,
2840+ ( LitKind :: CStr ( ..) , ty:: Ref ( _, inner_ty, _) ) if matches ! ( inner_ty. kind( ) , ty:: Adt ( def, _) if tcx. is_lang_item( def. did( ) , LangItem :: CStr ) ) => {
2841+ true
2842+ }
2843+ ( LitKind :: Int ( ..) , ty:: Uint ( _) ) if !neg => true ,
2844+ ( LitKind :: Int ( ..) , ty:: Int ( _) ) => true ,
2845+ ( LitKind :: Bool ( ..) , ty:: Bool ) => true ,
2846+ ( LitKind :: Float ( ..) , ty:: Float ( _) ) => true ,
2847+ ( LitKind :: Char ( ..) , ty:: Char ) => true ,
2848+ ( LitKind :: Err ( ..) , _) => true ,
2849+ _ => false ,
2850+ }
2851+ }
2852+
2853+ fn const_lit_description ( & self , kind : & LitKind ) -> & ' static str {
2854+ match * kind {
2855+ LitKind :: Str ( ..) => "&str" ,
2856+ LitKind :: ByteStr ( ..) => "&[u8]" ,
2857+ LitKind :: CStr ( ..) => "&CStr" ,
2858+ LitKind :: Byte ( ..) => "u8" ,
2859+ LitKind :: Int ( _, suffix) => match suffix {
2860+ LitIntType :: Signed ( int_ty) => int_ty. name_str ( ) ,
2861+ LitIntType :: Unsigned ( uint_ty) => uint_ty. name_str ( ) ,
2862+ LitIntType :: Unsuffixed => "{integer}" ,
2863+ } ,
2864+ LitKind :: Float ( _, suffix) => match suffix {
2865+ LitFloatType :: Suffixed ( float_ty) => float_ty. name_str ( ) ,
2866+ LitFloatType :: Unsuffixed => "{float}" ,
2867+ } ,
2868+ LitKind :: Bool ( ..) => "bool" ,
2869+ LitKind :: Char ( ..) => "char" ,
2870+ LitKind :: Err ( ..) => "erroneous literal" ,
2871+ }
2872+ }
2873+
28142874 #[ instrument( skip( self ) , level = "debug" ) ]
28152875 fn try_lower_anon_const_lit (
28162876 & self ,
0 commit comments