@@ -11,6 +11,8 @@ use rustc_target::abi::VariantIdx;
1111
1212use std:: iter;
1313
14+ use crate :: errors:: { GenericConstantTooComplex , GenericConstantTooComplexSub } ;
15+
1416/// Destructures array, ADT or tuple constants into the constants
1517/// of their fields.
1618pub ( crate ) fn destructure_const < ' tcx > (
@@ -93,26 +95,25 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
9395 self . body . exprs [ self . body_id ] . span
9496 }
9597
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+ } ) ;
104104
105105 Err ( reported)
106106 }
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+ } ) ;
116117
117118 Err ( reported)
118119 }
@@ -243,22 +244,23 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
243244 & ExprKind :: Scope { value, .. } => self . recurse_build ( value) ?,
244245 & ExprKind :: PlaceTypeAscription { source, .. }
245246 | & ExprKind :: ValueTypeAscription { source, .. } => self . recurse_build ( source) ?,
246- & ExprKind :: Literal { lit, neg} => {
247+ & ExprKind :: Literal { lit, neg } => {
247248 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+ } ;
258260
259261 self . nodes . push ( Node :: Leaf ( constant) )
260262 }
261- & ExprKind :: NonHirLiteral { lit , user_ty : _} => {
263+ & ExprKind :: NonHirLiteral { lit, user_ty : _ } => {
262264 let val = ty:: ValTree :: from_scalar_int ( lit) ;
263265 self . nodes . push ( Node :: Leaf ( ty:: Const :: from_value ( self . tcx , val, node. ty ) ) )
264266 }
@@ -269,19 +271,17 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
269271 & ExprKind :: NamedConst { def_id, substs, user_ty : _ } => {
270272 let uneval = ty:: Unevaluated :: new ( ty:: WithOptConstParam :: unknown ( def_id) , substs) ;
271273
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 } ) ;
276277
277278 self . nodes . push ( Node :: Leaf ( constant) )
278279 }
279280
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 } ) ;
285285 self . nodes . push ( Node :: Leaf ( const_param) )
286286 }
287287
@@ -312,13 +312,13 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
312312 // }
313313 // ```
314314 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+ {
316317 self . recurse_build ( * e) ?
317318 } else {
318- self . maybe_supported_error (
319+ self . maybe_supported_error ( GenericConstantTooComplexSub :: BlockNotSupported (
319320 node. span ,
320- "blocks are not supported in generic constant" ,
321- ) ?
321+ ) ) ?
322322 }
323323 }
324324 // `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a
@@ -332,7 +332,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
332332 let arg = self . recurse_build ( source) ?;
333333 self . nodes . push ( Node :: Cast ( CastKind :: As , arg, node. ty ) )
334334 }
335- ExprKind :: Borrow { arg, ..} => {
335+ ExprKind :: Borrow { arg, .. } => {
336336 let arg_node = & self . body . exprs [ * arg] ;
337337
338338 // Skip reborrows for now until we allow Deref/Borrow/AddressOf
@@ -341,84 +341,77 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
341341 if let ExprKind :: Deref { arg } = arg_node. kind {
342342 self . recurse_build ( arg) ?
343343 } else {
344- self . maybe_supported_error (
344+ self . maybe_supported_error ( GenericConstantTooComplexSub :: BorrowNotSupported (
345345 node. span ,
346- "borrowing is not supported in generic constants" ,
347- ) ?
346+ ) ) ?
348347 }
349348 }
350349 // 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 ) ,
354352 ) ?,
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 ) ,
358355 ) ?,
359356 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 ) ,
362358 ) ?,
363359 ExprKind :: Tuple { .. } => self . maybe_supported_error (
364- node. span ,
365- "tuple construction is not supported in generic constants" ,
360+ GenericConstantTooComplexSub :: TupleNotSupported ( node. span ) ,
366361 ) ?,
367362 ExprKind :: Index { .. } => self . maybe_supported_error (
368- node. span ,
369- "indexing is not supported in generic constant" ,
363+ GenericConstantTooComplexSub :: IndexNotSupported ( node. span ) ,
370364 ) ?,
371365 ExprKind :: Field { .. } => self . maybe_supported_error (
372- node. span ,
373- "field access is not supported in generic constant" ,
366+ GenericConstantTooComplexSub :: FieldNotSupported ( node. span ) ,
374367 ) ?,
375368 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 ) ,
382370 ) ?,
371+ ExprKind :: Adt ( _) => self
372+ . maybe_supported_error ( GenericConstantTooComplexSub :: AdtNotSupported ( node. span ) ) ?,
383373 // 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+ }
395386
396387 ExprKind :: Unary { .. } => unreachable ! ( ) ,
397388 // 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+ }
402395 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 ) ) ?
404400 }
405- ExprKind :: Closure { .. } | ExprKind :: Return { .. } => self . error (
406- node. span ,
407- "closures and function keywords are not supported in generic constants" ,
408- ) ?,
409401 // 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+ }
412405 ExprKind :: InlineAsm { .. } => {
413- self . error ( node. span , "assembly is not supported in generic constants" ) ?
406+ self . error ( GenericConstantTooComplexSub :: InlineAsmNotSupported ( node. span ) ) ?
414407 }
415408
416409 // we dont permit let stmts so `VarRef` and `UpvarRef` cant happen
417410 ExprKind :: VarRef { .. }
418411 | ExprKind :: UpvarRef { .. }
419412 | ExprKind :: StaticRef { .. }
420413 | ExprKind :: ThreadLocalRef ( _) => {
421- self . error ( node. span , "unsupported operation in generic constant" ) ?
414+ self . error ( GenericConstantTooComplexSub :: OperationNotSupported ( node. span ) ) ?
422415 }
423416 } )
424417 }
0 commit comments