@@ -11,6 +11,8 @@ use rustc_target::abi::VariantIdx;
11
11
12
12
use std:: iter;
13
13
14
+ use crate :: errors:: { GenericConstantTooComplex , GenericConstantTooComplexSub } ;
15
+
14
16
/// Destructures array, ADT or tuple constants into the constants
15
17
/// of their fields.
16
18
pub ( crate ) fn destructure_const < ' tcx > (
@@ -93,26 +95,25 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
93
95
self . body . exprs [ self . body_id ] . span
94
96
}
95
97
96
- fn error ( & mut self , span : Span , msg : & str ) -> Result < !, ErrorGuaranteed > {
97
- let reported = self
98
- . tcx
99
- . sess
100
- . struct_span_err ( self . root_span ( ) , "overly complex generic constant" )
101
- . span_label ( span, msg)
102
- . help ( "consider moving this anonymous constant into a `const` function" )
103
- . emit ( ) ;
98
+ fn error ( & mut self , sub : GenericConstantTooComplexSub ) -> Result < !, ErrorGuaranteed > {
99
+ let reported = self . tcx . sess . emit_err ( GenericConstantTooComplex {
100
+ span : self . root_span ( ) ,
101
+ maybe_supported : None ,
102
+ sub,
103
+ } ) ;
104
104
105
105
Err ( reported)
106
106
}
107
- fn maybe_supported_error ( & mut self , span : Span , msg : & str ) -> Result < !, ErrorGuaranteed > {
108
- let reported = self
109
- . tcx
110
- . sess
111
- . struct_span_err ( self . root_span ( ) , "overly complex generic constant" )
112
- . span_label ( span, msg)
113
- . help ( "consider moving this anonymous constant into a `const` function" )
114
- . note ( "this operation may be supported in the future" )
115
- . emit ( ) ;
107
+
108
+ fn maybe_supported_error (
109
+ & mut self ,
110
+ sub : GenericConstantTooComplexSub ,
111
+ ) -> Result < !, ErrorGuaranteed > {
112
+ let reported = self . tcx . sess . emit_err ( GenericConstantTooComplex {
113
+ span : self . root_span ( ) ,
114
+ maybe_supported : Some ( ( ) ) ,
115
+ sub,
116
+ } ) ;
116
117
117
118
Err ( reported)
118
119
}
@@ -243,22 +244,23 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
243
244
& ExprKind :: Scope { value, .. } => self . recurse_build ( value) ?,
244
245
& ExprKind :: PlaceTypeAscription { source, .. }
245
246
| & ExprKind :: ValueTypeAscription { source, .. } => self . recurse_build ( source) ?,
246
- & ExprKind :: Literal { lit, neg} => {
247
+ & ExprKind :: Literal { lit, neg } => {
247
248
let sp = node. span ;
248
- let constant =
249
- match self . tcx . at ( sp) . lit_to_const ( LitToConstInput { lit : & lit. node , ty : node. ty , neg } ) {
250
- Ok ( c) => c,
251
- Err ( LitToConstError :: Reported ) => {
252
- self . tcx . const_error ( node. ty )
253
- }
254
- Err ( LitToConstError :: TypeError ) => {
255
- bug ! ( "encountered type error in lit_to_const" )
256
- }
257
- } ;
249
+ let constant = match self . tcx . at ( sp) . lit_to_const ( LitToConstInput {
250
+ lit : & lit. node ,
251
+ ty : node. ty ,
252
+ neg,
253
+ } ) {
254
+ Ok ( c) => c,
255
+ Err ( LitToConstError :: Reported ) => self . tcx . const_error ( node. ty ) ,
256
+ Err ( LitToConstError :: TypeError ) => {
257
+ bug ! ( "encountered type error in lit_to_const" )
258
+ }
259
+ } ;
258
260
259
261
self . nodes . push ( Node :: Leaf ( constant) )
260
262
}
261
- & ExprKind :: NonHirLiteral { lit , user_ty : _} => {
263
+ & ExprKind :: NonHirLiteral { lit, user_ty : _ } => {
262
264
let val = ty:: ValTree :: from_scalar_int ( lit) ;
263
265
self . nodes . push ( Node :: Leaf ( ty:: Const :: from_value ( self . tcx , val, node. ty ) ) )
264
266
}
@@ -269,19 +271,17 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
269
271
& ExprKind :: NamedConst { def_id, substs, user_ty : _ } => {
270
272
let uneval = ty:: Unevaluated :: new ( ty:: WithOptConstParam :: unknown ( def_id) , substs) ;
271
273
272
- let constant = self . tcx . mk_const ( ty:: ConstS {
273
- kind : ty:: ConstKind :: Unevaluated ( uneval) ,
274
- ty : node. ty ,
275
- } ) ;
274
+ let constant = self
275
+ . tcx
276
+ . mk_const ( ty:: ConstS { kind : ty:: ConstKind :: Unevaluated ( uneval) , ty : node. ty } ) ;
276
277
277
278
self . nodes . push ( Node :: Leaf ( constant) )
278
279
}
279
280
280
- ExprKind :: ConstParam { param, ..} => {
281
- let const_param = self . tcx . mk_const ( ty:: ConstS {
282
- kind : ty:: ConstKind :: Param ( * param) ,
283
- ty : node. ty ,
284
- } ) ;
281
+ ExprKind :: ConstParam { param, .. } => {
282
+ let const_param = self
283
+ . tcx
284
+ . mk_const ( ty:: ConstS { kind : ty:: ConstKind :: Param ( * param) , ty : node. ty } ) ;
285
285
self . nodes . push ( Node :: Leaf ( const_param) )
286
286
}
287
287
@@ -312,13 +312,13 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
312
312
// }
313
313
// ```
314
314
ExprKind :: Block { block } => {
315
- if let thir:: Block { stmts : box [ ] , expr : Some ( e) , .. } = & self . body . blocks [ * block] {
315
+ if let thir:: Block { stmts : box [ ] , expr : Some ( e) , .. } = & self . body . blocks [ * block]
316
+ {
316
317
self . recurse_build ( * e) ?
317
318
} else {
318
- self . maybe_supported_error (
319
+ self . maybe_supported_error ( GenericConstantTooComplexSub :: BlockNotSupported (
319
320
node. span ,
320
- "blocks are not supported in generic constant" ,
321
- ) ?
321
+ ) ) ?
322
322
}
323
323
}
324
324
// `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a
@@ -332,7 +332,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
332
332
let arg = self . recurse_build ( source) ?;
333
333
self . nodes . push ( Node :: Cast ( CastKind :: As , arg, node. ty ) )
334
334
}
335
- ExprKind :: Borrow { arg, ..} => {
335
+ ExprKind :: Borrow { arg, .. } => {
336
336
let arg_node = & self . body . exprs [ * arg] ;
337
337
338
338
// Skip reborrows for now until we allow Deref/Borrow/AddressOf
@@ -341,84 +341,77 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
341
341
if let ExprKind :: Deref { arg } = arg_node. kind {
342
342
self . recurse_build ( arg) ?
343
343
} else {
344
- self . maybe_supported_error (
344
+ self . maybe_supported_error ( GenericConstantTooComplexSub :: BorrowNotSupported (
345
345
node. span ,
346
- "borrowing is not supported in generic constants" ,
347
- ) ?
346
+ ) ) ?
348
347
}
349
348
}
350
349
// FIXME(generic_const_exprs): We may want to support these.
351
- ExprKind :: AddressOf { .. } | ExprKind :: Deref { ..} => self . maybe_supported_error (
352
- node. span ,
353
- "dereferencing or taking the address is not supported in generic constants" ,
350
+ ExprKind :: AddressOf { .. } | ExprKind :: Deref { .. } => self . maybe_supported_error (
351
+ GenericConstantTooComplexSub :: AddressAndDerefNotSupported ( node. span ) ,
354
352
) ?,
355
- ExprKind :: Repeat { .. } | ExprKind :: Array { .. } => self . maybe_supported_error (
356
- node. span ,
357
- "array construction is not supported in generic constants" ,
353
+ ExprKind :: Repeat { .. } | ExprKind :: Array { .. } => self . maybe_supported_error (
354
+ GenericConstantTooComplexSub :: ArrayNotSupported ( node. span ) ,
358
355
) ?,
359
356
ExprKind :: NeverToAny { .. } => self . maybe_supported_error (
360
- node. span ,
361
- "converting nevers to any is not supported in generic constant" ,
357
+ GenericConstantTooComplexSub :: NeverToAnyNotSupported ( node. span ) ,
362
358
) ?,
363
359
ExprKind :: Tuple { .. } => self . maybe_supported_error (
364
- node. span ,
365
- "tuple construction is not supported in generic constants" ,
360
+ GenericConstantTooComplexSub :: TupleNotSupported ( node. span ) ,
366
361
) ?,
367
362
ExprKind :: Index { .. } => self . maybe_supported_error (
368
- node. span ,
369
- "indexing is not supported in generic constant" ,
363
+ GenericConstantTooComplexSub :: IndexNotSupported ( node. span ) ,
370
364
) ?,
371
365
ExprKind :: Field { .. } => self . maybe_supported_error (
372
- node. span ,
373
- "field access is not supported in generic constant" ,
366
+ GenericConstantTooComplexSub :: FieldNotSupported ( node. span ) ,
374
367
) ?,
375
368
ExprKind :: ConstBlock { .. } => self . maybe_supported_error (
376
- node. span ,
377
- "const blocks are not supported in generic constant" ,
378
- ) ?,
379
- ExprKind :: Adt ( _) => self . maybe_supported_error (
380
- node. span ,
381
- "struct/enum construction is not supported in generic constants" ,
369
+ GenericConstantTooComplexSub :: ConstBlockNotSupported ( node. span ) ,
382
370
) ?,
371
+ ExprKind :: Adt ( _) => self
372
+ . maybe_supported_error ( GenericConstantTooComplexSub :: AdtNotSupported ( node. span ) ) ?,
383
373
// dont know if this is correct
384
- ExprKind :: Pointer { .. } =>
385
- self . error ( node. span , "pointer casts are not allowed in generic constants" ) ?,
386
- ExprKind :: Yield { .. } =>
387
- self . error ( node. span , "generator control flow is not allowed in generic constants" ) ?,
388
- ExprKind :: Continue { .. } | ExprKind :: Break { .. } | ExprKind :: Loop { .. } => self
389
- . error (
390
- node. span ,
391
- "loops and loop control flow are not supported in generic constants" ,
392
- ) ?,
393
- ExprKind :: Box { .. } =>
394
- self . error ( node. span , "allocations are not allowed in generic constants" ) ?,
374
+ ExprKind :: Pointer { .. } => {
375
+ self . error ( GenericConstantTooComplexSub :: PointerNotSupported ( node. span ) ) ?
376
+ }
377
+ ExprKind :: Yield { .. } => {
378
+ self . error ( GenericConstantTooComplexSub :: YieldNotSupported ( node. span ) ) ?
379
+ }
380
+ ExprKind :: Continue { .. } | ExprKind :: Break { .. } | ExprKind :: Loop { .. } => {
381
+ self . error ( GenericConstantTooComplexSub :: LoopNotSupported ( node. span ) ) ?
382
+ }
383
+ ExprKind :: Box { .. } => {
384
+ self . error ( GenericConstantTooComplexSub :: BoxNotSupported ( node. span ) ) ?
385
+ }
395
386
396
387
ExprKind :: Unary { .. } => unreachable ! ( ) ,
397
388
// we handle valid unary/binary ops above
398
- ExprKind :: Binary { .. } =>
399
- self . error ( node. span , "unsupported binary operation in generic constants" ) ?,
400
- ExprKind :: LogicalOp { .. } =>
401
- self . error ( node. span , "unsupported operation in generic constants, short-circuiting operations would imply control flow" ) ?,
389
+ ExprKind :: Binary { .. } => {
390
+ self . error ( GenericConstantTooComplexSub :: BinaryNotSupported ( node. span ) ) ?
391
+ }
392
+ ExprKind :: LogicalOp { .. } => {
393
+ self . error ( GenericConstantTooComplexSub :: LogicalOpNotSupported ( node. span ) ) ?
394
+ }
402
395
ExprKind :: Assign { .. } | ExprKind :: AssignOp { .. } => {
403
- self . error ( node. span , "assignment is not supported in generic constants" ) ?
396
+ self . error ( GenericConstantTooComplexSub :: AssignNotSupported ( node. span ) ) ?
397
+ }
398
+ ExprKind :: Closure { .. } | ExprKind :: Return { .. } => {
399
+ self . error ( GenericConstantTooComplexSub :: ClosureAndReturnNotSupported ( node. span ) ) ?
404
400
}
405
- ExprKind :: Closure { .. } | ExprKind :: Return { .. } => self . error (
406
- node. span ,
407
- "closures and function keywords are not supported in generic constants" ,
408
- ) ?,
409
401
// let expressions imply control flow
410
- ExprKind :: Match { .. } | ExprKind :: If { .. } | ExprKind :: Let { .. } =>
411
- self . error ( node. span , "control flow is not supported in generic constants" ) ?,
402
+ ExprKind :: Match { .. } | ExprKind :: If { .. } | ExprKind :: Let { .. } => {
403
+ self . error ( GenericConstantTooComplexSub :: ControlFlowNotSupported ( node. span ) ) ?
404
+ }
412
405
ExprKind :: InlineAsm { .. } => {
413
- self . error ( node. span , "assembly is not supported in generic constants" ) ?
406
+ self . error ( GenericConstantTooComplexSub :: InlineAsmNotSupported ( node. span ) ) ?
414
407
}
415
408
416
409
// we dont permit let stmts so `VarRef` and `UpvarRef` cant happen
417
410
ExprKind :: VarRef { .. }
418
411
| ExprKind :: UpvarRef { .. }
419
412
| ExprKind :: StaticRef { .. }
420
413
| ExprKind :: ThreadLocalRef ( _) => {
421
- self . error ( node. span , "unsupported operation in generic constant" ) ?
414
+ self . error ( GenericConstantTooComplexSub :: OperationNotSupported ( node. span ) ) ?
422
415
}
423
416
} )
424
417
}
0 commit comments