@@ -216,6 +216,8 @@ enum ResolutionError<'a> {
216
216
ForwardDeclaredTyParam , // FIXME(const_generics:defaults)
217
217
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
218
218
ParamInTyOfConstParam ( Symbol ) ,
219
+ /// constant values inside of type parameter defaults must not depend on generic parameters.
220
+ ParamInAnonConstInTyDefault ( Symbol ) ,
219
221
/// Error E0735: type parameters with a default cannot use `Self`
220
222
SelfInTyParamDefault ,
221
223
/// Error E0767: use of unreachable label
@@ -2526,18 +2528,40 @@ impl<'a> Resolver<'a> {
2526
2528
}
2527
2529
}
2528
2530
Res :: Def ( DefKind :: TyParam , _) | Res :: SelfTy ( ..) => {
2531
+ let mut in_ty_param_default = false ;
2529
2532
for rib in ribs {
2530
2533
let has_generic_params = match rib. kind {
2531
2534
NormalRibKind
2532
2535
| ClosureOrAsyncRibKind
2533
2536
| AssocItemRibKind
2534
2537
| ModuleRibKind ( ..)
2535
- | MacroDefinition ( ..)
2536
- | ForwardTyParamBanRibKind
2537
- | ConstantItemRibKind => {
2538
+ | MacroDefinition ( ..) => {
2538
2539
// Nothing to do. Continue.
2539
2540
continue ;
2540
2541
}
2542
+
2543
+ // We only forbid constant items if we are inside of type defaults,
2544
+ // for example `struct Foo<T, U = [u8; std::mem::size_of::<T>()]>`
2545
+ ForwardTyParamBanRibKind => {
2546
+ in_ty_param_default = true ;
2547
+ continue ;
2548
+ }
2549
+ ConstantItemRibKind => {
2550
+ if in_ty_param_default {
2551
+ if record_used {
2552
+ self . report_error (
2553
+ span,
2554
+ ResolutionError :: ParamInAnonConstInTyDefault (
2555
+ rib_ident. name ,
2556
+ ) ,
2557
+ ) ;
2558
+ }
2559
+ return Res :: Err ;
2560
+ } else {
2561
+ continue ;
2562
+ }
2563
+ }
2564
+
2541
2565
// This was an attempt to use a type parameter outside its scope.
2542
2566
ItemRibKind ( has_generic_params) => has_generic_params,
2543
2567
FnItemRibKind => HasGenericParams :: Yes ,
@@ -2572,15 +2596,38 @@ impl<'a> Resolver<'a> {
2572
2596
// (spuriously) conflicting with the const param.
2573
2597
ribs. next ( ) ;
2574
2598
}
2599
+
2600
+ let mut in_ty_param_default = false ;
2575
2601
for rib in ribs {
2576
2602
let has_generic_params = match rib. kind {
2577
2603
NormalRibKind
2578
2604
| ClosureOrAsyncRibKind
2579
2605
| AssocItemRibKind
2580
2606
| ModuleRibKind ( ..)
2581
- | MacroDefinition ( ..)
2582
- | ForwardTyParamBanRibKind
2583
- | ConstantItemRibKind => continue ,
2607
+ | MacroDefinition ( ..) => continue ,
2608
+
2609
+ // We only forbid constant items if we are inside of type defaults,
2610
+ // for example `struct Foo<T, U = [u8; std::mem::size_of::<T>()]>`
2611
+ ForwardTyParamBanRibKind => {
2612
+ in_ty_param_default = true ;
2613
+ continue ;
2614
+ }
2615
+ ConstantItemRibKind => {
2616
+ if in_ty_param_default {
2617
+ if record_used {
2618
+ self . report_error (
2619
+ span,
2620
+ ResolutionError :: ParamInAnonConstInTyDefault (
2621
+ rib_ident. name ,
2622
+ ) ,
2623
+ ) ;
2624
+ }
2625
+ return Res :: Err ;
2626
+ } else {
2627
+ continue ;
2628
+ }
2629
+ }
2630
+
2584
2631
ItemRibKind ( has_generic_params) => has_generic_params,
2585
2632
FnItemRibKind => HasGenericParams :: Yes ,
2586
2633
ConstParamTyRibKind => {
0 commit comments