@@ -8,7 +8,7 @@ use rustc_hir::lang_items::LangItem;
88use rustc_middle:: mir:: * ;
99use rustc_middle:: span_bug;
1010use rustc_middle:: thir:: * ;
11- use rustc_middle:: ty:: { CanonicalUserTypeAnnotation , Ty } ;
11+ use rustc_middle:: ty:: { self , CanonicalUserTypeAnnotation , Ty } ;
1212use rustc_span:: DUMMY_SP ;
1313use rustc_span:: source_map:: Spanned ;
1414use rustc_trait_selection:: infer:: InferCtxtExt ;
@@ -17,7 +17,7 @@ use tracing::{debug, instrument};
1717use crate :: builder:: expr:: category:: { Category , RvalueFunc } ;
1818use crate :: builder:: matches:: { DeclareLetBindings , HasMatchGuard } ;
1919use crate :: builder:: { BlockAnd , BlockAndExtension , BlockFrame , Builder , NeedsTemporary } ;
20- use crate :: errors:: LoopMatchArmWithGuard ;
20+ use crate :: errors:: { LoopMatchArmWithGuard , LoopMatchUnsupportedType } ;
2121
2222impl < ' a , ' tcx > Builder < ' a , ' tcx > {
2323 /// Compile `expr`, storing the result into `destination`, which
@@ -253,6 +253,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
253253 // `in_const_continuable_scope`, which makes the match arms and their target basic
254254 // block available to the lowering of `#[const_continue]`.
255255
256+ fn is_supported_loop_match_type ( ty : Ty < ' _ > ) -> bool {
257+ if ty. is_integral ( ) {
258+ return true ;
259+ }
260+
261+ if let Some ( adt_def) = ty. ty_adt_def ( ) {
262+ if adt_def. adt_kind ( ) != ty:: AdtKind :: Enum {
263+ return false ;
264+ }
265+
266+ for variant in adt_def. variants ( ) {
267+ if !variant. fields . is_empty ( ) {
268+ return false ;
269+ }
270+ }
271+
272+ return true ;
273+ }
274+
275+ false
276+ }
277+
278+ let state_ty = this. thir . exprs [ state] . ty ;
279+ if !is_supported_loop_match_type ( state_ty) {
280+ let span = this. thir . exprs [ state] . span ;
281+ this. tcx . dcx ( ) . emit_fatal ( LoopMatchUnsupportedType { span, ty : state_ty } )
282+ }
283+
256284 let loop_block = this. cfg . start_new_block ( ) ;
257285
258286 // Start the loop.
0 commit comments