@@ -13,41 +13,6 @@ use rustc_trait_selection::traits::{
1313 StatementAsExpression ,
1414} ;
1515
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-
5116impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
5217 pub fn check_match (
5318 & self ,
@@ -154,7 +119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
154119 expr. span ,
155120 & arms[ 0 ] . body ,
156121 & 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) ,
158123 ) {
159124 tcx. ty_error ( )
160125 } else {
@@ -373,23 +338,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
373338 error
374339 }
375340
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+ }
385348
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 ,
391389 }
392- ) ;
390+ }
393391
394392 pub ( crate ) fn if_cause (
395393 & self ,
0 commit comments