@@ -774,57 +774,68 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
774774 let prev_diverges = self . diverges . get ( ) ;
775775 let ctxt = BreakableCtxt { coerce : Some ( coerce) , may_break : false } ;
776776
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+ }
782781
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 ) ;
825835 }
826836 }
827- coerce. coerce_forced_unit (
837+ }
838+ coerce. coerce_forced_unit (
828839 self ,
829840 & self . misc ( sp) ,
830841 & mut |err| {
@@ -837,21 +848,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
837848 // Our block must be a `assign desugar local; assignment`
838849 if let Some ( hir:: Node :: Block ( hir:: Block {
839850 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+ ] ,
855870 ..
856871 } ) ) = self . tcx . hir ( ) . find ( blk. hir_id )
857872 {
@@ -871,9 +886,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
871886 } ,
872887 false ,
873888 ) ;
874- }
875889 }
876- } ) ;
890+ }
891+ } ) ;
877892
878893 if ctxt. may_break {
879894 // If we can break from the block, then the block's exit is always reachable
0 commit comments