about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/mod.rs38
-rw-r--r--src/librustc_typeck/lib.rs3
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libstd/termination.rs14
-rw-r--r--src/libsyntax/feature_gate.rs3
-rw-r--r--src/test/compile-fail/feature-gate-termination_trait.rs13
-rw-r--r--src/test/compile-fail/termination-trait-not-satisfied.rs2
7 files changed, 47 insertions, 28 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index e99633519f4..7a49c3549ab 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -93,7 +93,6 @@ use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin};
 use rustc::infer::anon_types::AnonTypeDecl;
 use rustc::infer::type_variable::{TypeVariableOrigin};
 use rustc::middle::region;
-use rustc::middle::lang_items::TerminationTraitLangItem;
 use rustc::ty::subst::{Kind, Subst, Substs};
 use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode};
 use rustc::ty::{ParamTy, LvaluePreference, NoPreference, PreferMutLvalue};
@@ -1066,24 +1065,25 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
     }
     fcx.demand_suptype(span, ret_ty, actual_return_ty);
 
-    // 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()));
-                    },
-                    _ => {},
+    if fcx.tcx.sess.features.borrow().termination_trait {
+        // If the termination trait language item is activated, check that the main return type
+        // implements the termination trait.
+        if let Some(term_id) = fcx.tcx.lang_items().termination() {
+            if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() {
+                if id == fn_id {
+                    match fcx.sess().entry_type.get() {
+                        Some(config::EntryMain) => {
+                            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 f02998f7edf..0b2f59abf4f 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -203,7 +203,8 @@ 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() {
+            let expected_return_type = if tcx.lang_items().termination().is_some()
+                && tcx.sess.features.borrow().termination_trait {
                 // we take the return type of the given main function, the real check is done
                 // in `check_fn`
                 actual.output().skip_binder()
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 3a7a57fe2b8..171c108e3aa 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -503,7 +503,7 @@ pub mod rt;
 // The trait to support returning arbitrary types in the main function
 mod termination;
 
-#[unstable(feature = "termination_trait", issue = "0")]
+#[unstable(feature = "termination_trait", issue = "43301")]
 pub use self::termination::Termination;
 
 // Include a number of private modules that exist solely to provide
diff --git a/src/libstd/termination.rs b/src/libstd/termination.rs
index 5eeaa542b41..ee1dc5470a8 100644
--- a/src/libstd/termination.rs
+++ b/src/libstd/termination.rs
@@ -20,7 +20,7 @@ use libc;
 /// The default implementations are returning `libc::EXIT_SUCCESS` to indicate
 /// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned.
 #[cfg_attr(not(stage0), lang = "termination")]
-#[unstable(feature = "termination_trait", issue = "0")]
+#[unstable(feature = "termination_trait", issue = "43301")]
 #[rustc_on_unimplemented =
   "`main` can only return types that implement {Termination}, not `{Self}`"]
 pub trait Termination {
@@ -29,12 +29,12 @@ pub trait Termination {
     fn report(self) -> i32;
 }
 
-#[unstable(feature = "termination_trait", issue = "0")]
+#[unstable(feature = "termination_trait", issue = "43301")]
 impl Termination for () {
     fn report(self) -> i32 { libc::EXIT_SUCCESS }
 }
 
-#[unstable(feature = "termination_trait", issue = "0")]
+#[unstable(feature = "termination_trait", issue = "43301")]
 impl<T: Termination, E: Error> Termination for Result<T, E> {
     fn report(self) -> i32 {
         match self {
@@ -47,7 +47,7 @@ impl<T: Termination, E: Error> Termination for Result<T, E> {
     }
 }
 
-#[unstable(feature = "termination_trait", issue = "0")]
+#[unstable(feature = "termination_trait", issue = "43301")]
 fn print_error<E: Error>(err: E) {
     eprintln!("Error: {}", err.description());
 
@@ -56,19 +56,19 @@ fn print_error<E: Error>(err: E) {
     }
 }
 
-#[unstable(feature = "termination_trait", issue = "0")]
+#[unstable(feature = "termination_trait", issue = "43301")]
 impl Termination for ! {
     fn report(self) -> i32 { unreachable!(); }
 }
 
-#[unstable(feature = "termination_trait", issue = "0")]
+#[unstable(feature = "termination_trait", issue = "43301")]
 impl Termination for bool {
     fn report(self) -> i32 {
         if self { libc::EXIT_SUCCESS } else { libc::EXIT_FAILURE }
     }
 }
 
-#[unstable(feature = "termination_trait", issue = "0")]
+#[unstable(feature = "termination_trait", issue = "43301")]
 impl Termination for i32 {
     fn report(self) -> i32 {
         self
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index f8d6b419f7a..dde917b4d95 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -444,6 +444,9 @@ declare_features! (
 
     // Nested `impl Trait`
     (active, nested_impl_trait, "1.24.0", Some(34511)),
+
+    // Termination trait in main (RFC 1937)
+    (active, termination_trait, "1.24.0", Some(43301)),
 );
 
 declare_features! (
diff --git a/src/test/compile-fail/feature-gate-termination_trait.rs b/src/test/compile-fail/feature-gate-termination_trait.rs
new file mode 100644
index 00000000000..5a56445b64e
--- /dev/null
+++ b/src/test/compile-fail/feature-gate-termination_trait.rs
@@ -0,0 +1,13 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() -> i32 { //~ ERROR main function has wrong type [E0580]
+    0
+}
diff --git a/src/test/compile-fail/termination-trait-not-satisfied.rs b/src/test/compile-fail/termination-trait-not-satisfied.rs
index 178a9b8cf59..788c38c55be 100644
--- a/src/test/compile-fail/termination-trait-not-satisfied.rs
+++ b/src/test/compile-fail/termination-trait-not-satisfied.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(termination_trait)]
+
 struct ReturnType {}
 
 fn main() -> ReturnType { //~ ERROR `ReturnType: std::Termination` is not satisfied