@@ -15,6 +15,7 @@ use crate::errors::{
15
15
} ;
16
16
use crate :: middle:: resolve_bound_vars as rbv;
17
17
use crate :: require_c_abi_if_c_variadic;
18
+ use hir:: def:: CtorKind ;
18
19
use rustc_ast:: TraitObjectSyntax ;
19
20
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
20
21
use rustc_errors:: {
@@ -34,7 +35,9 @@ use rustc_middle::middle::stability::AllowUnstable;
34
35
use rustc_middle:: ty:: fold:: FnMutDelegate ;
35
36
use rustc_middle:: ty:: subst:: { self , GenericArgKind , InternalSubsts , SubstsRef } ;
36
37
use rustc_middle:: ty:: GenericParamDefKind ;
37
- use rustc_middle:: ty:: { self , Const , IsSuggestable , Ty , TyCtxt , TypeVisitableExt } ;
38
+ use rustc_middle:: ty:: {
39
+ self , Const , IsSuggestable , Ty , TyCtxt , TypeVisitableExt , UnevaluatedConst ,
40
+ } ;
38
41
use rustc_middle:: ty:: { DynKind , ToPredicate } ;
39
42
use rustc_session:: lint:: builtin:: { AMBIGUOUS_ASSOCIATED_ITEMS , BARE_TRAIT_OBJECTS } ;
40
43
use rustc_span:: edit_distance:: find_best_match_for_name;
@@ -449,15 +452,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
449
452
( & GenericParamDefKind :: Type { has_default, .. } , GenericArg :: Infer ( inf) ) => {
450
453
handle_ty_args ( has_default, & inf. to_ty ( ) )
451
454
}
452
- ( GenericParamDefKind :: Const { .. } , GenericArg :: Const ( ct) ) => match ct. kind {
453
- // FIXME(const_arg_kind)
454
- hir:: ConstArgKind :: AnonConst ( _, ct) => {
455
- let did = ct. def_id ;
456
- tcx. feed_anon_const_type ( did, tcx. type_of ( param. def_id ) ) ;
457
- ty:: Const :: from_anon_const ( tcx, did) . into ( )
458
- }
459
- hir:: ConstArgKind :: Param ( _, _) => todo ! ( ) ,
460
- } ,
455
+ ( GenericParamDefKind :: Const { .. } , GenericArg :: Const ( ct) ) => {
456
+ self . astconv . ast_const_to_const ( ct, param. def_id ) . into ( )
457
+ }
461
458
( & GenericParamDefKind :: Const { .. } , hir:: GenericArg :: Infer ( inf) ) => {
462
459
let ty = tcx
463
460
. at ( self . span )
@@ -3757,6 +3754,129 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
3757
3754
}
3758
3755
}
3759
3756
}
3757
+
3758
+ #[ instrument( level = "debug" , skip( self ) , ret) ]
3759
+ pub fn ast_const_to_const (
3760
+ & self ,
3761
+ ast_ct : & hir:: ConstArg < ' _ > ,
3762
+ param_def_id : DefId ,
3763
+ ) -> Const < ' tcx > {
3764
+ let tcx = self . tcx ( ) ;
3765
+
3766
+ match ast_ct. kind {
3767
+ hir:: ConstArgKind :: AnonConst ( _, ct) => {
3768
+ tcx. feed_anon_const_type ( ct. def_id , tcx. type_of ( param_def_id) ) ;
3769
+ Const :: from_anon_const ( tcx, ct. def_id )
3770
+ }
3771
+ hir:: ConstArgKind :: Param ( _, path) => match path {
3772
+ hir:: QPath :: Resolved ( _, path) => match path. res {
3773
+ Res :: Def ( def_kind, def_id) => match def_kind {
3774
+ DefKind :: ConstParam => {
3775
+ self . prohibit_generics ( path. segments . iter ( ) , |_| { } ) ;
3776
+ let param_ty = tcx. type_of ( def_id) . subst_identity ( ) ;
3777
+
3778
+ match tcx. named_bound_var ( ast_ct. hir_id ( ) ) {
3779
+ Some ( rbv:: ResolvedArg :: EarlyBound ( _) ) => {
3780
+ // Find the name and index of the const parameter by indexing the generics of
3781
+ // the parent item and construct a `ParamConst`.
3782
+ let item_def_id = tcx. parent ( def_id) ;
3783
+ let generics = tcx. generics_of ( item_def_id) ;
3784
+ let index = generics. param_def_id_to_index [ & def_id] ;
3785
+ let name = tcx. item_name ( def_id) ;
3786
+ tcx. mk_const ( ty:: ParamConst :: new ( index, name) , param_ty)
3787
+ }
3788
+ Some ( rbv:: ResolvedArg :: LateBound ( debruijn, index, _) ) => tcx
3789
+ . mk_const (
3790
+ ty:: ConstKind :: Bound (
3791
+ debruijn,
3792
+ ty:: BoundVar :: from_u32 ( index) ,
3793
+ ) ,
3794
+ param_ty,
3795
+ ) ,
3796
+ Some ( rbv:: ResolvedArg :: Error ( guar) ) => {
3797
+ tcx. const_error_with_guaranteed ( param_ty, guar)
3798
+ }
3799
+ arg => bug ! (
3800
+ "unexpected bound var resolution for {:?}: {arg:?}" ,
3801
+ ast_ct. hir_id( )
3802
+ ) ,
3803
+ }
3804
+ }
3805
+ DefKind :: Const => {
3806
+ let ( last, prev) = path. segments . split_last ( ) . unwrap ( ) ;
3807
+ self . prohibit_generics ( prev. iter ( ) , |_| { } ) ;
3808
+ let substs = self . ast_path_substs_for_ty ( ast_ct. span ( ) , def_id, last) ;
3809
+ tcx. mk_const (
3810
+ UnevaluatedConst { def : def_id, substs } ,
3811
+ tcx. type_of ( def_id) . subst ( tcx, substs) ,
3812
+ )
3813
+ }
3814
+
3815
+ DefKind :: Ctor ( _, _) => todo ! ( ) ,
3816
+ DefKind :: Fn => todo ! ( ) ,
3817
+
3818
+ DefKind :: AssocFn | DefKind :: AssocConst => {
3819
+ unimplemented ! ( "multi segment paths are not supported" )
3820
+ }
3821
+
3822
+ // FIXME(const_arg_kind): somewhere else should be emitting this
3823
+ DefKind :: Static ( _) => {
3824
+ let e = tcx
3825
+ . sess
3826
+ . span_err ( ast_ct. span ( ) , "no static access in consts allowed" ) ;
3827
+ tcx. const_error_with_guaranteed ( tcx. ty_error ( e) , e)
3828
+ }
3829
+
3830
+ DefKind :: OpaqueTy
3831
+ | DefKind :: InlineConst
3832
+ | DefKind :: ForeignMod
3833
+ | DefKind :: AnonConst
3834
+ | DefKind :: Macro ( _)
3835
+ | DefKind :: ExternCrate
3836
+ | DefKind :: Use
3837
+ | DefKind :: LifetimeParam
3838
+ | DefKind :: Struct
3839
+ | DefKind :: Union
3840
+ | DefKind :: Enum
3841
+ | DefKind :: Variant
3842
+ | DefKind :: Trait
3843
+ | DefKind :: TyAlias
3844
+ | DefKind :: ForeignTy
3845
+ | DefKind :: TraitAlias
3846
+ | DefKind :: AssocTy
3847
+ | DefKind :: TyParam
3848
+ | DefKind :: ImplTraitPlaceholder
3849
+ | DefKind :: Field
3850
+ | DefKind :: GlobalAsm
3851
+ | DefKind :: Impl { .. }
3852
+ | DefKind :: Closure
3853
+ | DefKind :: Mod
3854
+ | DefKind :: Generator => bug ! ( "unexpected path res of const arg" ) ,
3855
+ } ,
3856
+
3857
+ Res :: SelfCtor ( _) => todo ! ( ) ,
3858
+
3859
+ Res :: Err
3860
+ | Res :: Local ( _)
3861
+ | Res :: ToolMod
3862
+ | Res :: NonMacroAttr ( _)
3863
+ | Res :: PrimTy ( _)
3864
+ | Res :: SelfTyParam { .. }
3865
+ | Res :: SelfTyAlias { .. } => {
3866
+ let e = tcx. sess . delay_span_bug (
3867
+ ast_ct. span ( ) ,
3868
+ format ! ( "unexpected path res {:?} of const arg {:?}" , path. res, ast_ct) ,
3869
+ ) ;
3870
+ tcx. const_error_with_guaranteed ( tcx. ty_error ( e) , e)
3871
+ }
3872
+ } ,
3873
+ hir:: QPath :: TypeRelative ( _, _) => {
3874
+ bug ! ( "multi-segment path consts are not yet supported" )
3875
+ }
3876
+ hir:: QPath :: LangItem ( _, _, _) => unimplemented ! ( ) ,
3877
+ } ,
3878
+ }
3879
+ }
3760
3880
}
3761
3881
3762
3882
pub trait InferCtxtExt < ' tcx > {
0 commit comments