@@ -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