@@ -215,7 +215,9 @@ enum ResolutionError<'a> {
215
215
/// Error E0128: type parameters with a default cannot use forward-declared identifiers.
216
216
ForwardDeclaredTyParam , // FIXME(const_generics:defaults)
217
217
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
218
- ParamInTyOfConstArg ( Symbol ) ,
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
@@ -2514,7 +2516,7 @@ impl<'a> Resolver<'a> {
2514
2516
}
2515
2517
ConstParamTyRibKind => {
2516
2518
if record_used {
2517
- self . report_error ( span, ParamInTyOfConstArg ( rib_ident. name ) ) ;
2519
+ self . report_error ( span, ParamInTyOfConstParam ( rib_ident. name ) ) ;
2518
2520
}
2519
2521
return Res :: Err ;
2520
2522
}
@@ -2526,26 +2528,48 @@ 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 ,
2544
2568
ConstParamTyRibKind => {
2545
2569
if record_used {
2546
2570
self . report_error (
2547
2571
span,
2548
- ResolutionError :: ParamInTyOfConstArg ( rib_ident. name ) ,
2572
+ ResolutionError :: ParamInTyOfConstParam ( rib_ident. name ) ,
2549
2573
) ;
2550
2574
}
2551
2575
return Res :: Err ;
@@ -2572,22 +2596,45 @@ 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 => {
2587
2634
if record_used {
2588
2635
self . report_error (
2589
2636
span,
2590
- ResolutionError :: ParamInTyOfConstArg ( rib_ident. name ) ,
2637
+ ResolutionError :: ParamInTyOfConstParam ( rib_ident. name ) ,
2591
2638
) ;
2592
2639
}
2593
2640
return Res :: Err ;
0 commit comments