@@ -29,7 +29,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
2929use rustc_hir:: def_id:: { DefId , LocalDefId , LOCAL_CRATE } ;
3030use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
3131use rustc_hir:: weak_lang_items;
32- use rustc_hir:: { GenericParamKind , Node } ;
32+ use rustc_hir:: { GenericParamKind , HirId , Node } ;
3333use rustc_middle:: hir:: map:: blocks:: FnLikeNode ;
3434use rustc_middle:: hir:: map:: Map ;
3535use rustc_middle:: middle:: codegen_fn_attrs:: { CodegenFnAttrFlags , CodegenFnAttrs } ;
@@ -1155,6 +1155,35 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
11551155 }
11561156}
11571157
1158+ struct AnonConstInParamListDetector {
1159+ in_param_list : bool ,
1160+ found_anon_const_in_list : bool ,
1161+ ct : HirId ,
1162+ }
1163+
1164+ impl < ' v > Visitor < ' v > for AnonConstInParamListDetector {
1165+ type Map = intravisit:: ErasedMap < ' v > ;
1166+
1167+ fn nested_visit_map ( & mut self ) -> NestedVisitorMap < Self :: Map > {
1168+ NestedVisitorMap :: None
1169+ }
1170+
1171+ fn visit_generic_param ( & mut self , p : & ' v hir:: GenericParam < ' v > ) {
1172+ let prev = self . in_param_list ;
1173+ self . in_param_list = true ;
1174+ intravisit:: walk_generic_param ( self , p) ;
1175+ self . in_param_list = prev;
1176+ }
1177+
1178+ fn visit_anon_const ( & mut self , c : & ' v hir:: AnonConst ) {
1179+ if self . in_param_list && self . ct == c. hir_id {
1180+ self . found_anon_const_in_list = true ;
1181+ } else {
1182+ intravisit:: walk_anon_const ( self , c)
1183+ }
1184+ }
1185+ }
1186+
11581187fn generics_of ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> ty:: Generics {
11591188 use rustc_hir:: * ;
11601189
@@ -1176,10 +1205,32 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
11761205 let parent_id = tcx. hir ( ) . get_parent_item ( hir_id) ;
11771206 let parent_def_id = tcx. hir ( ) . local_def_id ( parent_id) ;
11781207
1179- // HACK(eddyb) this provides the correct generics when
1180- // `feature(const_generics)` is enabled, so that const expressions
1181- // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
1182- if tcx. lazy_normalization ( ) {
1208+ let mut in_param_list = false ;
1209+ for ( _parent, node) in tcx. hir ( ) . parent_iter ( hir_id) {
1210+ if let Some ( generics) = node. generics ( ) {
1211+ let mut visitor = AnonConstInParamListDetector {
1212+ in_param_list : false ,
1213+ found_anon_const_in_list : false ,
1214+ ct : hir_id,
1215+ } ;
1216+
1217+ visitor. visit_generics ( generics) ;
1218+ in_param_list = visitor. found_anon_const_in_list ;
1219+ break ;
1220+ }
1221+ }
1222+
1223+ if in_param_list {
1224+ // We do not allow generic parameters in anon consts if we are inside
1225+ // of a param list.
1226+ //
1227+ // This affects both default type bindings, e.g. `struct<T, U = [u8; std::mem::size_of::<T>()]>(T, U)`,
1228+ // and the types of const parameters, e.g. `struct V<const N: usize, const M: [u8; N]>();`.
1229+ None
1230+ } else if tcx. lazy_normalization ( ) {
1231+ // HACK(eddyb) this provides the correct generics when
1232+ // `feature(const_generics)` is enabled, so that const expressions
1233+ // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
11831234 Some ( parent_def_id. to_def_id ( ) )
11841235 } else {
11851236 let parent_node = tcx. hir ( ) . get ( tcx. hir ( ) . get_parent_node ( hir_id) ) ;
0 commit comments