about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/mod.rs33
-rw-r--r--src/librustc_typeck/lib.rs11
2 files changed, 28 insertions, 16 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 159340d19a7..e99633519f4 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1066,20 +1066,25 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
     }
     fcx.demand_suptype(span, ret_ty, actual_return_ty);
 
-    if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() {
-        if id == fn_id {
-            match fcx.sess().entry_type.get() {
-                Some(config::EntryMain) => {
-                    let term_id = fcx.tcx.require_lang_item(TerminationTraitLangItem);
-
-                    let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty)));
-                    let trait_ref = ty::TraitRef::new(term_id, substs);
-                    let cause = traits::ObligationCause::new(span, fn_id,
-                                                             ObligationCauseCode::MainFunctionType);
-                    inherited.register_predicate(
-                        traits::Obligation::new(cause, param_env, trait_ref.to_predicate()));
-                },
-                _ => {},
+    // If the termination trait language item is activated, check that the main return type
+    // implements the termination trait.
+    if fcx.tcx.lang_items().termination().is_some() {
+        if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() {
+            if id == fn_id {
+                match fcx.sess().entry_type.get() {
+                    Some(config::EntryMain) => {
+                        let term_id = fcx.tcx.require_lang_item(TerminationTraitLangItem);
+
+                        let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty)));
+                        let trait_ref = ty::TraitRef::new(term_id, substs);
+                        let cause = traits::ObligationCause::new(
+                            span, fn_id, ObligationCauseCode::MainFunctionType);
+
+                        inherited.register_predicate(
+                            traits::Obligation::new(cause, param_env, trait_ref.to_predicate()));
+                    },
+                    _ => {},
+                }
             }
         }
     }
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index f11328b2424..f02998f7edf 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -203,12 +203,19 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             }
 
             let actual = tcx.fn_sig(main_def_id);
+            let expected_return_type = if tcx.lang_items().termination().is_some() {
+                // we take the return type of the given main function, the real check is done
+                // in `check_fn`
+                actual.output().skip_binder()
+            } else {
+                // standard () main return type
+                tcx.mk_nil()
+            };
 
             let se_ty = tcx.mk_fn_ptr(ty::Binder(
                 tcx.mk_fn_sig(
                     iter::empty(),
-                    // the return type is checked in `check_fn`
-                    actual.output().skip_binder(),
+                    expected_return_type,
                     false,
                     hir::Unsafety::Normal,
                     Abi::Rust