@@ -451,7 +451,7 @@ pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
451451 // expects the types within the function to be consistent.
452452 err_count_on_creation : usize ,
453453
454- ret_ty : Ty < ' tcx > ,
454+ ret_ty : Option < Ty < ' tcx > > ,
455455
456456 ps : RefCell < UnsafetyState > ,
457457
@@ -785,11 +785,12 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
785785
786786 // Create the function context. This is either derived from scratch or,
787787 // in the case of function expressions, based on the outer context.
788- let mut fcx = FnCtxt :: new ( inherited, fn_sig. output ( ) , body. id ) ;
788+ let mut fcx = FnCtxt :: new ( inherited, body. id ) ;
789+ let ret_ty = fn_sig. output ( ) ;
789790 * fcx. ps . borrow_mut ( ) = UnsafetyState :: function ( unsafety, unsafety_id) ;
790791
791- fcx. require_type_is_sized ( fcx . ret_ty , decl. output . span ( ) , traits:: ReturnType ) ;
792- fcx. ret_ty = fcx. instantiate_anon_types ( & fcx . ret_ty ) ;
792+ fcx. require_type_is_sized ( ret_ty, decl. output . span ( ) , traits:: ReturnType ) ;
793+ fcx. ret_ty = fcx. instantiate_anon_types ( & ret_ty) ;
793794 fn_sig = fcx. tcx . mk_fn_sig ( fn_sig. inputs ( ) . iter ( ) . cloned ( ) , & fcx. ret_ty , fn_sig. variadic ) ;
794795
795796 {
@@ -821,7 +822,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
821822
822823 inherited. tables . borrow_mut ( ) . liberated_fn_sigs . insert ( fn_id, fn_sig) ;
823824
824- fcx. check_expr_coercable_to_type ( body, fcx. ret_ty ) ;
825+ fcx. check_expr_coercable_to_type ( body, fcx. ret_ty . unwrap ( ) ) ;
825826
826827 fcx
827828}
@@ -1245,7 +1246,7 @@ fn check_const_with_type<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
12451246 expected_type : Ty < ' tcx > ,
12461247 id : ast:: NodeId ) {
12471248 ccx. inherited ( id) . enter ( |inh| {
1248- let fcx = FnCtxt :: new ( & inh, expected_type , expr. id ) ;
1249+ let fcx = FnCtxt :: new ( & inh, expr. id ) ;
12491250 fcx. require_type_is_sized ( expected_type, expr. span , traits:: ConstSized ) ;
12501251
12511252 // Gather locals in statics (because of block expressions).
@@ -1530,15 +1531,14 @@ enum TupleArgumentsFlag {
15301531
15311532impl < ' a , ' gcx , ' tcx > FnCtxt < ' a , ' gcx , ' tcx > {
15321533 pub fn new ( inh : & ' a Inherited < ' a , ' gcx , ' tcx > ,
1533- rty : Ty < ' tcx > ,
15341534 body_id : ast:: NodeId )
15351535 -> FnCtxt < ' a , ' gcx , ' tcx > {
15361536 FnCtxt {
15371537 ast_ty_to_ty_cache : RefCell :: new ( NodeMap ( ) ) ,
15381538 body_id : body_id,
15391539 writeback_errors : Cell :: new ( false ) ,
15401540 err_count_on_creation : inh. tcx . sess . err_count ( ) ,
1541- ret_ty : rty ,
1541+ ret_ty : None ,
15421542 ps : RefCell :: new ( UnsafetyState :: function ( hir:: Unsafety :: Normal ,
15431543 ast:: CRATE_NODE_ID ) ) ,
15441544 diverges : Cell :: new ( Diverges :: Maybe ) ,
@@ -3705,14 +3705,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
37053705 }
37063706 hir:: ExprAgain ( _) => { tcx. types . never }
37073707 hir:: ExprRet ( ref expr_opt) => {
3708- if let Some ( ref e) = * expr_opt {
3709- self . check_expr_coercable_to_type ( & e, self . ret_ty ) ;
3708+ if self . ret_ty . is_none ( ) {
3709+ struct_span_err ! ( self . tcx. sess, expr. span, E0571 ,
3710+ "return statement cannot be out of a function scope" ) . emit ( ) ;
3711+ } else if let Some ( ref e) = * expr_opt {
3712+ self . check_expr_coercable_to_type ( & e, self . ret_ty . unwrap ( ) ) ;
37103713 } else {
37113714 match self . eq_types ( false ,
37123715 & self . misc ( expr. span ) ,
3713- self . ret_ty ,
3714- tcx. mk_nil ( ) )
3715- {
3716+ self . ret_ty . unwrap ( ) ,
3717+ tcx. mk_nil ( ) ) {
37163718 Ok ( ok) => self . register_infer_ok_obligations ( ok) ,
37173719 Err ( _) => {
37183720 struct_span_err ! ( tcx. sess, expr. span, E0069 ,
0 commit comments