@@ -774,57 +774,68 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
774
774
let prev_diverges = self . diverges . get ( ) ;
775
775
let ctxt = BreakableCtxt { coerce : Some ( coerce) , may_break : false } ;
776
776
777
- let ( ctxt, ( ) ) =
778
- self . with_breakable_ctxt ( blk. hir_id , ctxt, || {
779
- for ( pos, s) in blk. stmts . iter ( ) . enumerate ( ) {
780
- self . check_stmt ( s, blk. stmts . len ( ) - 1 == pos) ;
781
- }
777
+ let ( ctxt, ( ) ) = self . with_breakable_ctxt ( blk. hir_id , ctxt, || {
778
+ for ( pos, s) in blk. stmts . iter ( ) . enumerate ( ) {
779
+ self . check_stmt ( s, blk. stmts . len ( ) - 1 == pos) ;
780
+ }
782
781
783
- // check the tail expression **without** holding the
784
- // `enclosing_breakables` lock below.
785
- let tail_expr_ty = tail_expr. map ( |t| self . check_expr_with_expectation ( t, expected) ) ;
786
-
787
- let mut enclosing_breakables = self . enclosing_breakables . borrow_mut ( ) ;
788
- let ctxt = enclosing_breakables. find_breakable ( blk. hir_id ) ;
789
- let coerce = ctxt. coerce . as_mut ( ) . unwrap ( ) ;
790
- if let Some ( tail_expr_ty) = tail_expr_ty {
791
- let tail_expr = tail_expr. unwrap ( ) ;
792
- let span = self . get_expr_coercion_span ( tail_expr) ;
793
- let cause =
794
- self . cause ( span, ObligationCauseCode :: BlockTailExpression ( blk. hir_id ) ) ;
795
- coerce. coerce ( self , & cause, tail_expr, tail_expr_ty) ;
796
- } else {
797
- // Subtle: if there is no explicit tail expression,
798
- // that is typically equivalent to a tail expression
799
- // of `()` -- except if the block diverges. In that
800
- // case, there is no value supplied from the tail
801
- // expression (assuming there are no other breaks,
802
- // this implies that the type of the block will be
803
- // `!`).
804
- //
805
- // #41425 -- label the implicit `()` as being the
806
- // "found type" here, rather than the "expected type".
807
- if !self . diverges . get ( ) . is_always ( ) {
808
- // #50009 -- Do not point at the entire fn block span, point at the return type
809
- // span, as it is the cause of the requirement, and
810
- // `consider_hint_about_removing_semicolon` will point at the last expression
811
- // if it were a relevant part of the error. This improves usability in editors
812
- // that highlight errors inline.
813
- let mut sp = blk. span ;
814
- let mut fn_span = None ;
815
- if let Some ( ( decl, ident) ) = self . get_parent_fn_decl ( blk. hir_id ) {
816
- let ret_sp = decl. output . span ( ) ;
817
- if let Some ( block_sp) = self . parent_item_span ( blk. hir_id ) {
818
- // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
819
- // output would otherwise be incorrect and even misleading. Make sure
820
- // the span we're aiming at correspond to a `fn` body.
821
- if block_sp == blk. span {
822
- sp = ret_sp;
823
- fn_span = Some ( ident. span ) ;
824
- }
782
+ // check the tail expression **without** holding the
783
+ // `enclosing_breakables` lock below.
784
+ let tail_expr_ty = tail_expr. map ( |t| self . check_expr_with_expectation ( t, expected) ) ;
785
+
786
+ let mut enclosing_breakables = self . enclosing_breakables . borrow_mut ( ) ;
787
+ let ctxt = enclosing_breakables. find_breakable ( blk. hir_id ) ;
788
+ let coerce = ctxt. coerce . as_mut ( ) . unwrap ( ) ;
789
+ if let Some ( tail_expr_ty) = tail_expr_ty {
790
+ let tail_expr = tail_expr. unwrap ( ) ;
791
+ let span = self . get_expr_coercion_span ( tail_expr) ;
792
+ let cause = self . cause ( span, ObligationCauseCode :: BlockTailExpression ( blk. hir_id ) ) ;
793
+ let ty_for_diagnostic = coerce. merged_ty ( ) ;
794
+ // We use coerce_inner here because we want to augment the error
795
+ // suggesting to wrap the block in square brackets if it might've
796
+ // been mistaken array syntax
797
+ coerce. coerce_inner (
798
+ self ,
799
+ & cause,
800
+ Some ( tail_expr) ,
801
+ tail_expr_ty,
802
+ Some ( & mut |diag : & mut Diagnostic | {
803
+ self . suggest_block_to_brackets ( diag, blk, tail_expr_ty, ty_for_diagnostic) ;
804
+ } ) ,
805
+ false ,
806
+ ) ;
807
+ } else {
808
+ // Subtle: if there is no explicit tail expression,
809
+ // that is typically equivalent to a tail expression
810
+ // of `()` -- except if the block diverges. In that
811
+ // case, there is no value supplied from the tail
812
+ // expression (assuming there are no other breaks,
813
+ // this implies that the type of the block will be
814
+ // `!`).
815
+ //
816
+ // #41425 -- label the implicit `()` as being the
817
+ // "found type" here, rather than the "expected type".
818
+ if !self . diverges . get ( ) . is_always ( ) {
819
+ // #50009 -- Do not point at the entire fn block span, point at the return type
820
+ // span, as it is the cause of the requirement, and
821
+ // `consider_hint_about_removing_semicolon` will point at the last expression
822
+ // if it were a relevant part of the error. This improves usability in editors
823
+ // that highlight errors inline.
824
+ let mut sp = blk. span ;
825
+ let mut fn_span = None ;
826
+ if let Some ( ( decl, ident) ) = self . get_parent_fn_decl ( blk. hir_id ) {
827
+ let ret_sp = decl. output . span ( ) ;
828
+ if let Some ( block_sp) = self . parent_item_span ( blk. hir_id ) {
829
+ // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
830
+ // output would otherwise be incorrect and even misleading. Make sure
831
+ // the span we're aiming at correspond to a `fn` body.
832
+ if block_sp == blk. span {
833
+ sp = ret_sp;
834
+ fn_span = Some ( ident. span ) ;
825
835
}
826
836
}
827
- coerce. coerce_forced_unit (
837
+ }
838
+ coerce. coerce_forced_unit (
828
839
self ,
829
840
& self . misc ( sp) ,
830
841
& mut |err| {
@@ -837,21 +848,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
837
848
// Our block must be a `assign desugar local; assignment`
838
849
if let Some ( hir:: Node :: Block ( hir:: Block {
839
850
stmts :
840
- [ hir:: Stmt {
841
- kind :
842
- hir:: StmtKind :: Local ( hir:: Local {
843
- source : hir:: LocalSource :: AssignDesugar ( _) ,
844
- ..
845
- } ) ,
846
- ..
847
- } , hir:: Stmt {
848
- kind :
849
- hir:: StmtKind :: Expr ( hir:: Expr {
850
- kind : hir:: ExprKind :: Assign ( ..) ,
851
- ..
852
- } ) ,
853
- ..
854
- } ] ,
851
+ [
852
+ hir:: Stmt {
853
+ kind :
854
+ hir:: StmtKind :: Local ( hir:: Local {
855
+ source :
856
+ hir:: LocalSource :: AssignDesugar ( _) ,
857
+ ..
858
+ } ) ,
859
+ ..
860
+ } ,
861
+ hir:: Stmt {
862
+ kind :
863
+ hir:: StmtKind :: Expr ( hir:: Expr {
864
+ kind : hir:: ExprKind :: Assign ( ..) ,
865
+ ..
866
+ } ) ,
867
+ ..
868
+ } ,
869
+ ] ,
855
870
..
856
871
} ) ) = self . tcx . hir ( ) . find ( blk. hir_id )
857
872
{
@@ -871,9 +886,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
871
886
} ,
872
887
false ,
873
888
) ;
874
- }
875
889
}
876
- } ) ;
890
+ }
891
+ } ) ;
877
892
878
893
if ctxt. may_break {
879
894
// If we can break from the block, then the block's exit is always reachable
0 commit comments