File tree Expand file tree Collapse file tree 2 files changed +74
-4
lines changed Expand file tree Collapse file tree 2 files changed +74
-4
lines changed Original file line number Diff line number Diff line change @@ -137,10 +137,24 @@ impl<'a> InferenceContext<'a> {
137137
138138 self . coerce_merge_branch ( & then_ty, & else_ty)
139139 }
140- Expr :: Block { statements, tail, .. } => {
141- // FIXME: Breakable block inference
142- self . infer_block ( statements, * tail, expected)
143- }
140+ Expr :: Block { statements, tail, label } => match label {
141+ Some ( _) => {
142+ let break_ty = self . table . new_type_var ( ) ;
143+ self . breakables . push ( BreakableContext {
144+ may_break : false ,
145+ break_ty : break_ty. clone ( ) ,
146+ label : label. clone ( ) ,
147+ } ) ;
148+ let ty = self . infer_block ( statements, * tail, & Expectation :: has_type ( break_ty) ) ;
149+ let ctxt = self . breakables . pop ( ) . expect ( "breakable stack broken" ) ;
150+ if ctxt. may_break {
151+ ctxt. break_ty
152+ } else {
153+ ty
154+ }
155+ }
156+ None => self . infer_block ( statements, * tail, expected) ,
157+ } ,
144158 Expr :: Unsafe { body } => self . infer_expr ( * body, expected) ,
145159 Expr :: TryBlock { body } => {
146160 let _inner = self . infer_expr ( * body, expected) ;
Original file line number Diff line number Diff line change @@ -2074,6 +2074,62 @@ fn infer_labelled_break_with_val() {
20742074 ) ;
20752075}
20762076
2077+ #[ test]
2078+ fn infer_labelled_block_break_with_val ( ) {
2079+ check_infer (
2080+ r#"
2081+ fn default<T>() -> T { loop {} }
2082+ fn foo() {
2083+ let _x = 'outer: {
2084+ let inner = 'inner: {
2085+ let i = default();
2086+ if (break 'outer i) {
2087+ break 'inner 5i8;
2088+ } else if true {
2089+ break 'inner 6;
2090+ }
2091+ break 'inner 'innermost: { 0 };
2092+ 42
2093+ };
2094+ break 'outer inner < 8;
2095+ };
2096+ }
2097+ "# ,
2098+ expect ! [ [ r#"
2099+ 21..32 '{ loop {} }': T
2100+ 23..30 'loop {}': !
2101+ 28..30 '{}': ()
2102+ 42..381 '{ ... }; }': ()
2103+ 52..54 '_x': bool
2104+ 65..378 '{ ... }': bool
2105+ 79..84 'inner': i8
2106+ 95..339 '{ ... }': i8
2107+ 113..114 'i': bool
2108+ 117..124 'default': fn default<bool>() -> bool
2109+ 117..126 'default()': bool
2110+ 140..270 'if (br... }': ()
2111+ 144..158 'break 'outer i': !
2112+ 157..158 'i': bool
2113+ 160..209 '{ ... }': ()
2114+ 178..194 'break ...er 5i8': !
2115+ 191..194 '5i8': i8
2116+ 215..270 'if tru... }': ()
2117+ 218..222 'true': bool
2118+ 223..270 '{ ... }': ()
2119+ 241..255 'break 'inner 6': !
2120+ 254..255 '6': i8
2121+ 283..313 'break ... { 0 }': !
2122+ 308..313 '{ 0 }': i8
2123+ 310..311 '0': i8
2124+ 327..329 '42': i8
2125+ 349..371 'break ...er < 8': !
2126+ 362..367 'inner': i8
2127+ 362..371 'inner < 8': bool
2128+ 370..371 '8': i8
2129+ "# ] ] ,
2130+ ) ;
2131+ }
2132+
20772133#[ test]
20782134fn generic_default ( ) {
20792135 check_infer (
You can’t perform that action at this time.
0 commit comments