@@ -4,7 +4,7 @@ use rustc_errors::{Applicability, Diag};
4
4
use rustc_hir as hir;
5
5
use rustc_hir:: def:: Res ;
6
6
use rustc_hir:: intravisit:: Visitor ;
7
- use rustc_infer:: infer:: { DefineOpaqueTypes , InferOk } ;
7
+ use rustc_infer:: infer:: DefineOpaqueTypes ;
8
8
use rustc_middle:: bug;
9
9
use rustc_middle:: ty:: adjustment:: AllowTwoPhase ;
10
10
use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
@@ -166,7 +166,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
166
166
/// Requires that the two types unify, and prints an error message if
167
167
/// they don't.
168
168
pub fn demand_suptype ( & self , sp : Span , expected : Ty < ' tcx > , actual : Ty < ' tcx > ) {
169
- if let Some ( e) = self . demand_suptype_diag ( sp, expected, actual) {
169
+ if let Err ( e) = self . demand_suptype_diag ( sp, expected, actual) {
170
170
e. emit ( ) ;
171
171
}
172
172
}
@@ -176,7 +176,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
176
176
sp : Span ,
177
177
expected : Ty < ' tcx > ,
178
178
actual : Ty < ' tcx > ,
179
- ) -> Option < Diag < ' tcx > > {
179
+ ) -> Result < ( ) , Diag < ' tcx > > {
180
180
self . demand_suptype_with_origin ( & self . misc ( sp) , expected, actual)
181
181
}
182
182
@@ -186,18 +186,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
186
186
cause : & ObligationCause < ' tcx > ,
187
187
expected : Ty < ' tcx > ,
188
188
actual : Ty < ' tcx > ,
189
- ) -> Option < Diag < ' tcx > > {
190
- match self . at ( cause, self . param_env ) . sup ( DefineOpaqueTypes :: Yes , expected, actual) {
191
- Ok ( InferOk { obligations, value : ( ) } ) => {
192
- self . register_predicates ( obligations) ;
193
- None
194
- }
195
- Err ( e) => Some ( self . err_ctxt ( ) . report_mismatched_types ( cause, expected, actual, e) ) ,
196
- }
189
+ ) -> Result < ( ) , Diag < ' tcx > > {
190
+ self . at ( cause, self . param_env )
191
+ . sup ( DefineOpaqueTypes :: Yes , expected, actual)
192
+ . map ( |infer_ok| self . register_infer_ok_obligations ( infer_ok) )
193
+ . map_err ( |e| self . err_ctxt ( ) . report_mismatched_types ( cause, expected, actual, e) )
197
194
}
198
195
199
196
pub fn demand_eqtype ( & self , sp : Span , expected : Ty < ' tcx > , actual : Ty < ' tcx > ) {
200
- if let Some ( err) = self . demand_eqtype_diag ( sp, expected, actual) {
197
+ if let Err ( err) = self . demand_eqtype_diag ( sp, expected, actual) {
201
198
err. emit ( ) ;
202
199
}
203
200
}
@@ -207,7 +204,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
207
204
sp : Span ,
208
205
expected : Ty < ' tcx > ,
209
206
actual : Ty < ' tcx > ,
210
- ) -> Option < Diag < ' tcx > > {
207
+ ) -> Result < ( ) , Diag < ' tcx > > {
211
208
self . demand_eqtype_with_origin ( & self . misc ( sp) , expected, actual)
212
209
}
213
210
@@ -216,14 +213,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
216
213
cause : & ObligationCause < ' tcx > ,
217
214
expected : Ty < ' tcx > ,
218
215
actual : Ty < ' tcx > ,
219
- ) -> Option < Diag < ' tcx > > {
220
- match self . at ( cause, self . param_env ) . eq ( DefineOpaqueTypes :: Yes , expected, actual) {
221
- Ok ( InferOk { obligations, value : ( ) } ) => {
222
- self . register_predicates ( obligations) ;
223
- None
224
- }
225
- Err ( e) => Some ( self . err_ctxt ( ) . report_mismatched_types ( cause, expected, actual, e) ) ,
226
- }
216
+ ) -> Result < ( ) , Diag < ' tcx > > {
217
+ self . at ( cause, self . param_env )
218
+ . eq ( DefineOpaqueTypes :: Yes , expected, actual)
219
+ . map ( |infer_ok| self . register_infer_ok_obligations ( infer_ok) )
220
+ . map_err ( |e| self . err_ctxt ( ) . report_mismatched_types ( cause, expected, actual, e) )
227
221
}
228
222
229
223
pub fn demand_coerce (
@@ -234,12 +228,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
234
228
expected_ty_expr : Option < & ' tcx hir:: Expr < ' tcx > > ,
235
229
allow_two_phase : AllowTwoPhase ,
236
230
) -> Ty < ' tcx > {
237
- let ( ty, err) =
238
- self . demand_coerce_diag ( expr, checked_ty, expected, expected_ty_expr, allow_two_phase) ;
239
- if let Some ( err) = err {
240
- err. emit ( ) ;
231
+ match self . demand_coerce_diag ( expr, checked_ty, expected, expected_ty_expr, allow_two_phase)
232
+ {
233
+ Ok ( ty) => ty,
234
+ Err ( err) => {
235
+ err. emit ( ) ;
236
+ // Return the original type instead of an error type here, otherwise the type of `x` in
237
+ // `let x: u32 = ();` will be a type error, causing all subsequent usages of `x` to not
238
+ // report errors, even though `x` is definitely `u32`.
239
+ expected
240
+ }
241
241
}
242
- ty
243
242
}
244
243
245
244
/// Checks that the type of `expr` can be coerced to `expected`.
@@ -254,11 +253,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
254
253
expected : Ty < ' tcx > ,
255
254
mut expected_ty_expr : Option < & ' tcx hir:: Expr < ' tcx > > ,
256
255
allow_two_phase : AllowTwoPhase ,
257
- ) -> ( Ty < ' tcx > , Option < Diag < ' tcx > > ) {
256
+ ) -> Result < Ty < ' tcx > , Diag < ' tcx > > {
258
257
let expected = self . resolve_vars_with_obligations ( expected) ;
259
258
260
259
let e = match self . coerce ( expr, checked_ty, expected, allow_two_phase, None ) {
261
- Ok ( ty) => return ( ty, None ) ,
260
+ Ok ( ty) => return Ok ( ty) ,
262
261
Err ( e) => e,
263
262
} ;
264
263
@@ -275,7 +274,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
275
274
276
275
self . emit_coerce_suggestions ( & mut err, expr, expr_ty, expected, expected_ty_expr, Some ( e) ) ;
277
276
278
- ( expected , Some ( err) )
277
+ Err ( err)
279
278
}
280
279
281
280
/// Notes the point at which a variable is constrained to some type incompatible
0 commit comments