@@ -13,41 +13,6 @@ use rustc_trait_selection::traits::{
13
13
StatementAsExpression ,
14
14
} ;
15
15
16
- macro_rules! create_maybe_get_coercion_reason {
17
- ( $fn_name: ident, $node: expr) => {
18
- pub ( crate ) fn $fn_name( & self , hir_id: hir:: HirId , sp: Span ) -> Option <( Span , String ) > {
19
- let node = $node( self . tcx. hir( ) , hir_id) ;
20
- if let hir:: Node :: Block ( block) = node {
21
- // check that the body's parent is an fn
22
- let parent = self . tcx. hir( ) . get(
23
- self . tcx. hir( ) . get_parent_node( self . tcx. hir( ) . get_parent_node( block. hir_id) ) ,
24
- ) ;
25
- if let (
26
- Some ( expr) ,
27
- hir:: Node :: Item ( hir:: Item { kind: hir:: ItemKind :: Fn ( ..) , .. } ) ,
28
- ) = ( & block. expr, parent)
29
- {
30
- // check that the `if` expr without `else` is the fn body's expr
31
- if expr. span == sp {
32
- return self . get_fn_decl( hir_id) . and_then( |( fn_decl, _) | {
33
- let span = fn_decl. output. span( ) ;
34
- let snippet = self . tcx. sess. source_map( ) . span_to_snippet( span) . ok( ) ?;
35
- Some ( (
36
- span,
37
- format!( "expected `{}` because of this return type" , snippet) ,
38
- ) )
39
- } ) ;
40
- }
41
- }
42
- }
43
- if let hir:: Node :: Local ( hir:: Local { ty: Some ( _) , pat, .. } ) = node {
44
- return Some ( ( pat. span, "expected because of this assignment" . to_string( ) ) ) ;
45
- }
46
- None
47
- }
48
- } ;
49
- }
50
-
51
16
impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
52
17
pub fn check_match (
53
18
& self ,
@@ -154,7 +119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
154
119
expr. span ,
155
120
& arms[ 0 ] . body ,
156
121
& mut coercion,
157
- |hir_id, span| self . maybe_get_coercion_reason ( hir_id, span) ,
122
+ |hir_id, span| self . coercion_reason_match ( hir_id, span) ,
158
123
) {
159
124
tcx. ty_error ( )
160
125
} else {
@@ -373,23 +338,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
373
338
error
374
339
}
375
340
376
- create_maybe_get_coercion_reason ! (
377
- maybe_get_coercion_reason,
378
- |hir: rustc_middle:: hir:: map:: Map <' a>, id| {
379
- let arm_id = hir. get_parent_node( id) ;
380
- let match_id = hir. get_parent_node( arm_id) ;
381
- let containing_id = hir. get_parent_node( match_id) ;
382
- hir. get( containing_id)
383
- }
384
- ) ;
341
+ pub ( crate ) fn coercion_reason_if (
342
+ & self ,
343
+ hir_id : hir:: HirId ,
344
+ span : Span ,
345
+ ) -> Option < ( Span , String ) > {
346
+ self . coercion_reason_inner ( hir_id, span, 1 )
347
+ }
385
348
386
- create_maybe_get_coercion_reason ! (
387
- maybe_get_coercion_reason_if,
388
- |hir: rustc_middle:: hir:: map:: Map <' a>, id| {
389
- let rslt = hir. get_parent_node( hir. get_parent_node( id) ) ;
390
- hir. get( rslt)
349
+ pub ( crate ) fn coercion_reason_match (
350
+ & self ,
351
+ hir_id : hir:: HirId ,
352
+ span : Span ,
353
+ ) -> Option < ( Span , String ) > {
354
+ self . coercion_reason_inner ( hir_id, span, 2 )
355
+ }
356
+
357
+ fn coercion_reason_inner (
358
+ & self ,
359
+ hir_id : hir:: HirId ,
360
+ span : Span ,
361
+ parent_index : usize ,
362
+ ) -> Option < ( Span , String ) > {
363
+ let hir = self . tcx . hir ( ) ;
364
+ let mut parent_iter = hir. parent_iter ( hir_id) ;
365
+ let ( _, node) = parent_iter. nth ( parent_index) ?;
366
+ match node {
367
+ hir:: Node :: Block ( block) => {
368
+ let expr = block. expr ?;
369
+ // check that the body's parent is an fn
370
+ let ( _, parent) = parent_iter. nth ( 1 ) ?;
371
+ if let hir:: Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Fn ( ..) , .. } ) = parent {
372
+ // check that the `if` expr without `else` is the fn body's expr
373
+ if expr. span == span {
374
+ let ( fn_decl, _) = self . get_fn_decl ( hir_id) ?;
375
+ let span = fn_decl. output . span ( ) ;
376
+ let snippet = self . tcx . sess . source_map ( ) . span_to_snippet ( span) . ok ( ) ?;
377
+ return Some ( (
378
+ span,
379
+ format ! ( "expected `{}` because of this return type" , snippet) ,
380
+ ) ) ;
381
+ }
382
+ }
383
+ None
384
+ }
385
+ hir:: Node :: Local ( hir:: Local { ty : Some ( _) , pat, .. } ) => {
386
+ Some ( ( pat. span , "expected because of this assignment" . to_string ( ) ) )
387
+ }
388
+ _ => None ,
391
389
}
392
- ) ;
390
+ }
393
391
394
392
pub ( crate ) fn if_cause (
395
393
& self ,
0 commit comments