@@ -29,7 +29,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
29
29
use rustc_hir:: def_id:: { DefId , LocalDefId , LOCAL_CRATE } ;
30
30
use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
31
31
use rustc_hir:: weak_lang_items;
32
- use rustc_hir:: { GenericParamKind , Node } ;
32
+ use rustc_hir:: { GenericParamKind , HirId , Node } ;
33
33
use rustc_middle:: hir:: map:: blocks:: FnLikeNode ;
34
34
use rustc_middle:: hir:: map:: Map ;
35
35
use 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
1155
1155
}
1156
1156
}
1157
1157
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
+
1158
1187
fn generics_of ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> ty:: Generics {
1159
1188
use rustc_hir:: * ;
1160
1189
@@ -1176,10 +1205,32 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
1176
1205
let parent_id = tcx. hir ( ) . get_parent_item ( hir_id) ;
1177
1206
let parent_def_id = tcx. hir ( ) . local_def_id ( parent_id) ;
1178
1207
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.
1183
1234
Some ( parent_def_id. to_def_id ( ) )
1184
1235
} else {
1185
1236
let parent_node = tcx. hir ( ) . get ( tcx. hir ( ) . get_parent_node ( hir_id) ) ;
0 commit comments