@@ -1004,67 +1004,65 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty
10041004 ast_generics
10051005 . params
10061006 . iter ( )
1007- . filter_map ( |param| match param. kind {
1008- GenericParamKind :: Type {
1009- ref default,
1010- synthetic,
1011- ..
1012- } => {
1013- if param. name . ident ( ) . name == keywords:: SelfUpper . name ( ) {
1014- span_bug ! (
1015- param. span,
1016- "`Self` should not be the name of a regular parameter"
1017- ) ;
1018- }
1019-
1020- if !allow_defaults && default. is_some ( ) {
1021- if !tcx. features ( ) . default_type_parameter_fallback {
1022- tcx. lint_hir (
1023- lint:: builtin:: INVALID_TYPE_PARAM_DEFAULT ,
1024- param. hir_id ,
1007+ . filter_map ( |param| {
1008+ let kind = match param. kind {
1009+ GenericParamKind :: Type {
1010+ ref default,
1011+ synthetic,
1012+ ..
1013+ } => {
1014+ if param. name . ident ( ) . name == keywords:: SelfUpper . name ( ) {
1015+ span_bug ! (
10251016 param. span,
1026- & format ! (
1027- "defaults for type parameters are only allowed in \
1028- `struct`, `enum`, `type`, or `trait` definitions."
1029- ) ,
1017+ "`Self` should not be the name of a regular parameter"
10301018 ) ;
10311019 }
1032- }
10331020
1034- let ty_param = ty:: GenericParamDef {
1035- index : type_start + i as u32 ,
1036- name : param. name . ident ( ) . as_interned_str ( ) ,
1037- def_id : tcx. hir ( ) . local_def_id_from_hir_id ( param. hir_id ) ,
1038- pure_wrt_drop : param. pure_wrt_drop ,
1039- kind : ty:: GenericParamDefKind :: Type {
1021+ if !allow_defaults && default. is_some ( ) {
1022+ if !tcx. features ( ) . default_type_parameter_fallback {
1023+ tcx. lint_node (
1024+ lint:: builtin:: INVALID_TYPE_PARAM_DEFAULT ,
1025+ param. hir_id ,
1026+ param. span ,
1027+ & format ! (
1028+ "defaults for type parameters are only allowed in \
1029+ `struct`, `enum`, `type`, or `trait` definitions."
1030+ ) ,
1031+ ) ;
1032+ }
1033+ }
1034+
1035+ ty:: GenericParamDefKind :: Type {
10401036 has_default : default. is_some ( ) ,
10411037 object_lifetime_default : object_lifetime_defaults
10421038 . as_ref ( )
10431039 . map_or ( rl:: Set1 :: Empty , |o| o[ i] ) ,
10441040 synthetic,
1045- } ,
1046- } ;
1047- i += 1 ;
1048- Some ( ty_param)
1049- }
1050- GenericParamKind :: Const { .. } => {
1051- if param. name . ident ( ) . name == keywords:: SelfUpper . name ( ) {
1052- span_bug ! (
1053- param. span,
1054- "`Self` should not be the name of a regular parameter" ,
1055- ) ;
1041+ }
10561042 }
1043+ GenericParamKind :: Const { .. } => {
1044+ if param. name . ident ( ) . name == keywords:: SelfUpper . name ( ) {
1045+ span_bug ! (
1046+ param. span,
1047+ "`Self` should not be the name of a regular parameter" ,
1048+ ) ;
1049+ }
10571050
1058- // Emit an error, but skip the parameter rather than aborting to
1059- // continue to get other errors.
1060- tcx. sess . struct_span_err (
1061- param. span ,
1062- "const generics in any position are currently unsupported" ,
1063- ) . emit ( ) ;
1064- None
1065- }
1066- _ => None ,
1067- } ) ,
1051+ ty:: GenericParamDefKind :: Const
1052+ }
1053+ _ => return None ,
1054+ } ;
1055+
1056+ let param_def = ty:: GenericParamDef {
1057+ index : type_start + i as u32 ,
1058+ name : param. name . ident ( ) . as_interned_str ( ) ,
1059+ def_id : tcx. hir ( ) . local_def_id_from_hir_id ( param. hir_id ) ,
1060+ pure_wrt_drop : param. pure_wrt_drop ,
1061+ kind,
1062+ } ;
1063+ i += 1 ;
1064+ Some ( param_def)
1065+ } )
10681066 ) ;
10691067
10701068 // provide junk type parameter defs - the only place that
@@ -1284,44 +1282,111 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
12841282 tcx. mk_closure ( def_id, substs)
12851283 }
12861284
1287- Node :: AnonConst ( _) => match tcx . hir ( ) . get_by_hir_id (
1288- tcx. hir ( ) . get_parent_node_by_hir_id ( hir_id) )
1289- {
1290- Node :: Ty ( & hir:: Ty {
1291- node : hir:: TyKind :: Array ( _, ref constant) ,
1292- ..
1293- } )
1294- | Node :: Ty ( & hir:: Ty {
1295- node : hir:: TyKind :: Typeof ( ref constant) ,
1296- ..
1297- } )
1298- | Node :: Expr ( & hir:: Expr {
1299- node : ExprKind :: Repeat ( _, ref constant) ,
1300- ..
1301- } ) if constant. hir_id == hir_id =>
1302- {
1303- tcx. types . usize
1304- }
1285+ Node :: AnonConst ( _) => {
1286+ let parent_node = tcx. hir ( ) . get_by_hir_id ( tcx . hir ( ) . get_parent_node_by_hir_id ( hir_id) ) ;
1287+ match parent_node {
1288+ Node :: Ty ( & hir:: Ty {
1289+ node : hir:: TyKind :: Array ( _, ref constant) ,
1290+ ..
1291+ } )
1292+ | Node :: Ty ( & hir:: Ty {
1293+ node : hir:: TyKind :: Typeof ( ref constant) ,
1294+ ..
1295+ } )
1296+ | Node :: Expr ( & hir:: Expr {
1297+ node : ExprKind :: Repeat ( _, ref constant) ,
1298+ ..
1299+ } ) if constant. hir_id == hir_id =>
1300+ {
1301+ tcx. types . usize
1302+ }
13051303
1306- Node :: Variant ( & Spanned {
1307- node :
1308- VariantKind {
1309- disr_expr : Some ( ref e) ,
1310- ..
1311- } ,
1312- ..
1313- } ) if e. hir_id == hir_id =>
1314- {
1315- tcx. adt_def ( tcx. hir ( ) . get_parent_did_by_hir_id ( hir_id) )
1316- . repr
1317- . discr_type ( )
1318- . to_ty ( tcx)
1319- }
1304+ Node :: Variant ( & Spanned {
1305+ node :
1306+ VariantKind {
1307+ disr_expr : Some ( ref e) ,
1308+ ..
1309+ } ,
1310+ ..
1311+ } ) if e. hir_id == hir_id =>
1312+ {
1313+ tcx. adt_def ( tcx. hir ( ) . get_parent_did_by_hir_id ( hir_id) )
1314+ . repr
1315+ . discr_type ( )
1316+ . to_ty ( tcx)
1317+ }
13201318
1321- x => {
1322- bug ! ( "unexpected const parent in type_of_def_id(): {:?}" , x) ;
1319+ Node :: Ty ( & hir:: Ty { node : hir:: TyKind :: Path ( _) , .. } ) |
1320+ Node :: Expr ( & hir:: Expr { node : ExprKind :: Struct ( ..) , .. } ) |
1321+ Node :: Expr ( & hir:: Expr { node : ExprKind :: Path ( _) , .. } ) => {
1322+ let path = match parent_node {
1323+ Node :: Ty ( & hir:: Ty { node : hir:: TyKind :: Path ( ref path) , .. } ) |
1324+ Node :: Expr ( & hir:: Expr { node : ExprKind :: Path ( ref path) , .. } ) => {
1325+ path
1326+ }
1327+ Node :: Expr ( & hir:: Expr { node : ExprKind :: Struct ( ref path, ..) , .. } ) => {
1328+ & * path
1329+ }
1330+ _ => unreachable ! ( ) ,
1331+ } ;
1332+
1333+ match path {
1334+ QPath :: Resolved ( _, ref path) => {
1335+ let mut arg_index = 0 ;
1336+ let mut found_const = false ;
1337+ for seg in & path. segments {
1338+ if let Some ( generic_args) = & seg. args {
1339+ let args = & generic_args. args ;
1340+ for arg in args {
1341+ if let GenericArg :: Const ( ct) = arg {
1342+ if ct. value . id == node_id {
1343+ found_const = true ;
1344+ break ;
1345+ }
1346+ arg_index += 1 ;
1347+ }
1348+ }
1349+ }
1350+ }
1351+ // Sanity check to make sure everything is as expected.
1352+ if !found_const {
1353+ bug ! ( "no arg matching AnonConst in path" )
1354+ }
1355+ match path. def {
1356+ // We've encountered an `AnonConst` in some path, so we need to
1357+ // figure out which generic parameter it corresponds to and return
1358+ // the relevant type.
1359+ Def :: Struct ( def_id)
1360+ | Def :: Union ( def_id)
1361+ | Def :: Enum ( def_id)
1362+ | Def :: Fn ( def_id) => {
1363+ let generics = tcx. generics_of ( def_id) ;
1364+ let mut param_index = 0 ;
1365+ for param in & generics. params {
1366+ if let ty:: GenericParamDefKind :: Const = param. kind {
1367+ if param_index == arg_index {
1368+ return tcx. type_of ( param. def_id ) ;
1369+ }
1370+ param_index += 1 ;
1371+ }
1372+ }
1373+ // This is no generic parameter associated with the arg. This is
1374+ // probably from an extra arg where one is not needed.
1375+ return tcx. types . err ;
1376+ }
1377+ Def :: Err => tcx. types . err ,
1378+ x => bug ! ( "unexpected const parent path def {:?}" , x) ,
1379+ }
1380+ }
1381+ x => bug ! ( "unexpected const parent path {:?}" , x) ,
1382+ }
1383+ }
1384+
1385+ x => {
1386+ bug ! ( "unexpected const parent in type_of_def_id(): {:?}" , x) ;
1387+ }
13231388 }
1324- } ,
1389+ }
13251390
13261391 Node :: GenericParam ( param) => match & param. kind {
13271392 hir:: GenericParamKind :: Type { default : Some ( ref ty) , .. } |
0 commit comments