File tree 4 files changed +46
-41
lines changed
ide-diagnostics/src/handlers
4 files changed +46
-41
lines changed Original file line number Diff line number Diff line change @@ -688,7 +688,7 @@ impl<'a> InferenceContext<'a> {
688
688
}
689
689
}
690
690
691
- /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it.
691
+ /// Replaces ` Ty::Error` by a new type var, so we can maybe still infer it.
692
692
fn insert_type_vars_shallow ( & mut self , ty : Ty ) -> Ty {
693
693
match ty. kind ( Interner ) {
694
694
TyKind :: Error => self . table . new_type_var ( ) ,
Original file line number Diff line number Diff line change @@ -152,11 +152,20 @@ impl<'a> InferenceContext<'a> {
152
152
. 1
153
153
}
154
154
Expr :: TryBlock { body } => {
155
- self . with_breakable_ctx ( BreakableKind :: Border , self . err_ty ( ) , None , |this| {
156
- let _inner = this. infer_expr ( * body, expected) ;
155
+ // The type that is returned from the try block
156
+ let try_ty = self . table . new_type_var ( ) ;
157
+ if let Some ( ty) = expected. only_has_type ( & mut self . table ) {
158
+ self . unify ( & try_ty, & ty) ;
159
+ }
160
+
161
+ // The ok-ish type that is expected from the last expression
162
+ let ok_ty = self . resolve_associated_type ( try_ty. clone ( ) , self . resolve_ops_try_ok ( ) ) ;
163
+
164
+ self . with_breakable_ctx ( BreakableKind :: Block , ok_ty. clone ( ) , None , |this| {
165
+ this. infer_expr ( * body, & Expectation :: has_type ( ok_ty) ) ;
157
166
} ) ;
158
- // FIXME should be std::result::Result<{inner}, _>
159
- self . err_ty ( )
167
+
168
+ try_ty
160
169
}
161
170
Expr :: Async { body } => {
162
171
let ret_ty = self . table . new_type_var ( ) ;
Original file line number Diff line number Diff line change @@ -2064,17 +2064,17 @@ fn fn_pointer_return() {
2064
2064
fn block_modifiers_smoke_test ( ) {
2065
2065
check_infer (
2066
2066
r#"
2067
- //- minicore: future
2067
+ //- minicore: future, try
2068
2068
async fn main() {
2069
2069
let x = unsafe { 92 };
2070
2070
let y = async { async { () }.await };
2071
- let z = try { () };
2071
+ let z: core::ops::ControlFlow<(), _> = try { () };
2072
2072
let w = const { 92 };
2073
2073
let t = 'a: { 92 };
2074
2074
}
2075
2075
"# ,
2076
2076
expect ! [ [ r#"
2077
- 16..162 '{ ...2 }; }': ()
2077
+ 16..193 '{ ...2 }; }': ()
2078
2078
26..27 'x': i32
2079
2079
30..43 'unsafe { 92 }': i32
2080
2080
30..43 'unsafe { 92 }': i32
@@ -2086,17 +2086,17 @@ async fn main() {
2086
2086
65..77 'async { () }': impl Future<Output = ()>
2087
2087
65..83 'async ....await': ()
2088
2088
73..75 '()': ()
2089
- 95..96 'z': {unknown}
2090
- 99..109 'try { () }': ()
2091
- 99..109 'try { () }': {unknown}
2092
- 105..107 '()': ()
2093
- 119..120 'w': i32
2094
- 123..135 'const { 92 }': i32
2095
- 123..135 'const { 92 }': i32
2096
- 131..133 '92': i32
2097
- 145..146 't': i32
2098
- 149..159 ''a: { 92 }': i32
2099
- 155..157 '92': i32
2089
+ 95..96 'z': ControlFlow<(), ()>
2090
+ 130..140 'try { () }': ()
2091
+ 130..140 'try { () }': ControlFlow<(), ()>
2092
+ 136..138 '()': ()
2093
+ 150..151 'w': i32
2094
+ 154..166 'const { 92 }': i32
2095
+ 154..166 'const { 92 }': i32
2096
+ 162..164 '92': i32
2097
+ 176..177 't': i32
2098
+ 180..190 ''a: { 92 }': i32
2099
+ 186..188 '92': i32
2100
2100
"# ] ] ,
2101
2101
)
2102
2102
}
Original file line number Diff line number Diff line change @@ -38,12 +38,12 @@ fn foo() {
38
38
}
39
39
40
40
#[ test]
41
- fn try_blocks_are_borders ( ) {
41
+ fn async_blocks_are_borders ( ) {
42
42
check_diagnostics (
43
43
r#"
44
44
fn foo() {
45
45
'a: loop {
46
- try {
46
+ async {
47
47
break;
48
48
//^^^^^ error: break outside of loop
49
49
break 'a;
@@ -60,12 +60,12 @@ fn foo() {
60
60
}
61
61
62
62
#[ test]
63
- fn async_blocks_are_borders ( ) {
63
+ fn closures_are_borders ( ) {
64
64
check_diagnostics (
65
65
r#"
66
66
fn foo() {
67
67
'a: loop {
68
- try {
68
+ || {
69
69
break;
70
70
//^^^^^ error: break outside of loop
71
71
break 'a;
@@ -82,39 +82,35 @@ fn foo() {
82
82
}
83
83
84
84
#[ test]
85
- fn closures_are_borders ( ) {
85
+ fn blocks_pass_through ( ) {
86
86
check_diagnostics (
87
87
r#"
88
88
fn foo() {
89
89
'a: loop {
90
- try {
91
- break;
92
- //^^^^^ error: break outside of loop
93
- break 'a;
94
- //^^^^^^^^ error: break outside of loop
95
- continue;
96
- //^^^^^^^^ error: continue outside of loop
97
- continue 'a;
98
- //^^^^^^^^^^^ error: continue outside of loop
99
- };
90
+ {
91
+ break;
92
+ break 'a;
93
+ continue;
94
+ continue 'a;
95
+ }
100
96
}
101
97
}
102
98
"# ,
103
99
) ;
104
100
}
105
101
106
102
#[ test]
107
- fn blocks_pass_through ( ) {
103
+ fn try_blocks_pass_through ( ) {
108
104
check_diagnostics (
109
105
r#"
110
106
fn foo() {
111
107
'a: loop {
112
- {
113
- break;
114
- break 'a;
115
- continue;
116
- continue 'a;
117
- }
108
+ try {
109
+ break;
110
+ break 'a;
111
+ continue;
112
+ continue 'a;
113
+ };
118
114
}
119
115
}
120
116
"# ,
You can’t perform that action at this time.
0 commit comments