33//! instance of `AstConv`.
44
55use errors:: { Applicability , DiagnosticId } ;
6- use crate :: hir:: { self , GenericArg , GenericArgs } ;
6+ use crate :: hir:: { self , GenericArg , GenericArgs , ExprKind } ;
77use crate :: hir:: def:: Def ;
88use crate :: hir:: def_id:: DefId ;
99use crate :: hir:: HirVec ;
@@ -16,6 +16,7 @@ use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
1616use rustc:: ty:: { GenericParamDef , GenericParamDefKind } ;
1717use rustc:: ty:: subst:: { Kind , Subst , InternalSubsts , SubstsRef } ;
1818use rustc:: ty:: wf:: object_region_bounds;
19+ use rustc:: mir:: interpret:: ConstValue ;
1920use rustc_data_structures:: sync:: Lrc ;
2021use rustc_target:: spec:: abi;
2122use crate :: require_c_abi_if_c_variadic;
@@ -273,6 +274,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
273274 let param_counts = def. own_counts ( ) ;
274275 let arg_counts = args. own_counts ( ) ;
275276 let infer_lifetimes = position != GenericArgPosition :: Type && arg_counts. lifetimes == 0 ;
277+ let infer_consts = position != GenericArgPosition :: Type && arg_counts. consts == 0 ;
276278
277279 let mut defaults: ty:: GenericParamCount = Default :: default ( ) ;
278280 for param in & def. params {
@@ -281,6 +283,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
281283 GenericParamDefKind :: Type { has_default, .. } => {
282284 defaults. types += has_default as usize
283285 }
286+ GenericParamDefKind :: Const => {
287+ // FIXME(const_generics:defaults)
288+ }
284289 } ;
285290 }
286291
@@ -311,11 +316,15 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
311316 }
312317 }
313318
314- let check_kind_count = |kind,
315- required,
316- permitted,
317- provided,
318- offset| {
319+ let check_kind_count = |kind, required, permitted, provided, offset| {
320+ debug ! (
321+ "check_kind_count: kind: {} required: {} permitted: {} provided: {} offset: {}" ,
322+ kind,
323+ required,
324+ permitted,
325+ provided,
326+ offset
327+ ) ;
319328 // We enforce the following: `required` <= `provided` <= `permitted`.
320329 // For kinds without defaults (i.e., lifetimes), `required == permitted`.
321330 // For other kinds (i.e., types), `permitted` may be greater than `required`.
@@ -384,6 +393,17 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
384393 0 ,
385394 ) ;
386395 }
396+ // FIXME(const_generics:defaults)
397+ if !infer_consts || arg_counts. consts > param_counts. consts {
398+ check_kind_count (
399+ "const" ,
400+ param_counts. consts ,
401+ param_counts. consts ,
402+ arg_counts. consts ,
403+ arg_counts. lifetimes + arg_counts. types ,
404+ ) ;
405+ }
406+ // Note that type errors are currently be emitted *after* const errors.
387407 if !infer_types
388408 || arg_counts. types > param_counts. types - defaults. types - has_self as usize {
389409 check_kind_count (
@@ -495,7 +515,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
495515 ( Some ( & arg) , Some ( & param) ) => {
496516 match ( arg, & param. kind ) {
497517 ( GenericArg :: Lifetime ( _) , GenericParamDefKind :: Lifetime )
498- | ( GenericArg :: Type ( _) , GenericParamDefKind :: Type { .. } ) => {
518+ | ( GenericArg :: Type ( _) , GenericParamDefKind :: Type { .. } )
519+ | ( GenericArg :: Const ( _) , GenericParamDefKind :: Const ) => {
499520 substs. push ( provided_kind ( param, arg) ) ;
500521 args. next ( ) ;
501522 params. next ( ) ;
@@ -606,6 +627,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
606627 ( GenericParamDefKind :: Type { .. } , GenericArg :: Type ( ty) ) => {
607628 self . ast_ty_to_ty ( & ty) . into ( )
608629 }
630+ ( GenericParamDefKind :: Const , GenericArg :: Const ( ct) ) => {
631+ self . ast_const_to_const ( & ct. value , tcx. type_of ( param. def_id ) ) . into ( )
632+ }
609633 _ => unreachable ! ( ) ,
610634 }
611635 } ,
@@ -654,6 +678,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
654678 tcx. types . err . into ( )
655679 }
656680 }
681+ GenericParamDefKind :: Const => {
682+ // FIXME(const_generics:defaults)
683+ // We've already errored above about the mismatch.
684+ tcx. types . err . into ( )
685+ }
657686 }
658687 } ,
659688 ) ;
@@ -1609,6 +1638,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
16091638 // Case 3. Reference to a top-level value.
16101639 Def :: Fn ( def_id) |
16111640 Def :: Const ( def_id) |
1641+ Def :: ConstParam ( def_id) |
16121642 Def :: Static ( def_id, _) => {
16131643 path_segs. push ( PathSeg ( def_id, last) ) ;
16141644 }
@@ -1797,10 +1827,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
17971827 self . associated_path_to_ty ( ast_ty. hir_id , ast_ty. span , ty, def, segment, false ) . 0
17981828 }
17991829 hir:: TyKind :: Array ( ref ty, ref length) => {
1800- let length_def_id = tcx. hir ( ) . local_def_id_from_hir_id ( length. hir_id ) ;
1801- let substs = InternalSubsts :: identity_for_item ( tcx, length_def_id) ;
1802- let length = ty:: LazyConst :: Unevaluated ( length_def_id, substs) ;
1803- let length = tcx. mk_lazy_const ( length) ;
1830+ let length = self . ast_const_to_const ( length, tcx. types . usize ) ;
18041831 let array_ty = tcx. mk_ty ( ty:: Array ( self . ast_ty_to_ty ( & ty) , length) ) ;
18051832 self . normalize_ty ( ast_ty. span , array_ty)
18061833 }
@@ -1837,6 +1864,42 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
18371864 result_ty
18381865 }
18391866
1867+ pub fn ast_const_to_const (
1868+ & self ,
1869+ ast_const : & hir:: AnonConst ,
1870+ ty : Ty < ' tcx >
1871+ ) -> & ' tcx ty:: LazyConst < ' tcx > {
1872+ debug ! ( "ast_const_to_const(id={:?}, ast_const={:?})" , ast_const. id, ast_const) ;
1873+
1874+ let tcx = self . tcx ( ) ;
1875+ let def_id = tcx. hir ( ) . local_def_id ( ast_const. id ) ;
1876+
1877+ let mut lazy_const = ty:: LazyConst :: Unevaluated (
1878+ def_id,
1879+ Substs :: identity_for_item ( tcx, def_id)
1880+ ) ;
1881+
1882+ let expr = & tcx. hir ( ) . body ( ast_const. body ) . value ;
1883+ if let ExprKind :: Path ( ref qpath) = expr. node {
1884+ if let hir:: QPath :: Resolved ( _, ref path) = qpath {
1885+ if let Def :: ConstParam ( def_id) = path. def {
1886+ let node_id = tcx. hir ( ) . as_local_node_id ( def_id) . unwrap ( ) ;
1887+ let item_id = tcx. hir ( ) . get_parent_node ( node_id) ;
1888+ let item_def_id = tcx. hir ( ) . local_def_id ( item_id) ;
1889+ let generics = tcx. generics_of ( item_def_id) ;
1890+ let index = generics. param_def_id_to_index [ & tcx. hir ( ) . local_def_id ( node_id) ] ;
1891+ let name = tcx. hir ( ) . name ( node_id) . as_interned_str ( ) ;
1892+ lazy_const = ty:: LazyConst :: Evaluated ( ty:: Const {
1893+ val : ConstValue :: Param ( ty:: ParamConst :: new ( index, name) ) ,
1894+ ty,
1895+ } )
1896+ }
1897+ }
1898+ } ;
1899+
1900+ tcx. mk_lazy_const ( lazy_const)
1901+ }
1902+
18401903 pub fn impl_trait_ty_to_ty (
18411904 & self ,
18421905 def_id : DefId ,
0 commit comments