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> {
137
137
138
138
self . coerce_merge_branch ( & then_ty, & else_ty)
139
139
}
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
+ } ,
144
158
Expr :: Unsafe { body } => self . infer_expr ( * body, expected) ,
145
159
Expr :: TryBlock { body } => {
146
160
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() {
2074
2074
) ;
2075
2075
}
2076
2076
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
+
2077
2133
#[ test]
2078
2134
fn generic_default ( ) {
2079
2135
check_infer (
You can’t perform that action at this time.
0 commit comments