3
3
//! instance of `AstConv`.
4
4
5
5
use errors:: { Applicability , DiagnosticId } ;
6
- use crate :: hir:: { self , GenericArg , GenericArgs } ;
6
+ use crate :: hir:: { self , GenericArg , GenericArgs , ExprKind } ;
7
7
use crate :: hir:: def:: Def ;
8
8
use crate :: hir:: def_id:: DefId ;
9
9
use crate :: hir:: HirVec ;
@@ -16,6 +16,7 @@ use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
16
16
use rustc:: ty:: { GenericParamDef , GenericParamDefKind } ;
17
17
use rustc:: ty:: subst:: { Kind , Subst , InternalSubsts , SubstsRef } ;
18
18
use rustc:: ty:: wf:: object_region_bounds;
19
+ use rustc:: mir:: interpret:: ConstValue ;
19
20
use rustc_data_structures:: sync:: Lrc ;
20
21
use rustc_target:: spec:: abi;
21
22
use crate :: require_c_abi_if_c_variadic;
@@ -273,6 +274,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
273
274
let param_counts = def. own_counts ( ) ;
274
275
let arg_counts = args. own_counts ( ) ;
275
276
let infer_lifetimes = position != GenericArgPosition :: Type && arg_counts. lifetimes == 0 ;
277
+ let infer_consts = position != GenericArgPosition :: Type && arg_counts. consts == 0 ;
276
278
277
279
let mut defaults: ty:: GenericParamCount = Default :: default ( ) ;
278
280
for param in & def. params {
@@ -281,6 +283,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
281
283
GenericParamDefKind :: Type { has_default, .. } => {
282
284
defaults. types += has_default as usize
283
285
}
286
+ GenericParamDefKind :: Const => {
287
+ // FIXME(const_generics:defaults)
288
+ }
284
289
} ;
285
290
}
286
291
@@ -311,11 +316,15 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
311
316
}
312
317
}
313
318
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
+ ) ;
319
328
// We enforce the following: `required` <= `provided` <= `permitted`.
320
329
// For kinds without defaults (i.e., lifetimes), `required == permitted`.
321
330
// 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 {
384
393
0 ,
385
394
) ;
386
395
}
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.
387
407
if !infer_types
388
408
|| arg_counts. types > param_counts. types - defaults. types - has_self as usize {
389
409
check_kind_count (
@@ -495,7 +515,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
495
515
( Some ( & arg) , Some ( & param) ) => {
496
516
match ( arg, & param. kind ) {
497
517
( GenericArg :: Lifetime ( _) , GenericParamDefKind :: Lifetime )
498
- | ( GenericArg :: Type ( _) , GenericParamDefKind :: Type { .. } ) => {
518
+ | ( GenericArg :: Type ( _) , GenericParamDefKind :: Type { .. } )
519
+ | ( GenericArg :: Const ( _) , GenericParamDefKind :: Const ) => {
499
520
substs. push ( provided_kind ( param, arg) ) ;
500
521
args. next ( ) ;
501
522
params. next ( ) ;
@@ -606,6 +627,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
606
627
( GenericParamDefKind :: Type { .. } , GenericArg :: Type ( ty) ) => {
607
628
self . ast_ty_to_ty ( & ty) . into ( )
608
629
}
630
+ ( GenericParamDefKind :: Const , GenericArg :: Const ( ct) ) => {
631
+ self . ast_const_to_const ( & ct. value , tcx. type_of ( param. def_id ) ) . into ( )
632
+ }
609
633
_ => unreachable ! ( ) ,
610
634
}
611
635
} ,
@@ -654,6 +678,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
654
678
tcx. types . err . into ( )
655
679
}
656
680
}
681
+ GenericParamDefKind :: Const => {
682
+ // FIXME(const_generics:defaults)
683
+ // We've already errored above about the mismatch.
684
+ tcx. types . err . into ( )
685
+ }
657
686
}
658
687
} ,
659
688
) ;
@@ -1609,6 +1638,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
1609
1638
// Case 3. Reference to a top-level value.
1610
1639
Def :: Fn ( def_id) |
1611
1640
Def :: Const ( def_id) |
1641
+ Def :: ConstParam ( def_id) |
1612
1642
Def :: Static ( def_id, _) => {
1613
1643
path_segs. push ( PathSeg ( def_id, last) ) ;
1614
1644
}
@@ -1797,10 +1827,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
1797
1827
self . associated_path_to_ty ( ast_ty. hir_id , ast_ty. span , ty, def, segment, false ) . 0
1798
1828
}
1799
1829
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 ) ;
1804
1831
let array_ty = tcx. mk_ty ( ty:: Array ( self . ast_ty_to_ty ( & ty) , length) ) ;
1805
1832
self . normalize_ty ( ast_ty. span , array_ty)
1806
1833
}
@@ -1837,6 +1864,42 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
1837
1864
result_ty
1838
1865
}
1839
1866
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
+
1840
1903
pub fn impl_trait_ty_to_ty (
1841
1904
& self ,
1842
1905
def_id : DefId ,
0 commit comments