Skip to content

Commit c7a57d2

Browse files
committed
Adds termination_trait feature gate
1 parent 8f539b0 commit c7a57d2

File tree

7 files changed

+47
-28
lines changed

7 files changed

+47
-28
lines changed

src/librustc_typeck/check/mod.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin};
9393
use rustc::infer::anon_types::AnonTypeDecl;
9494
use rustc::infer::type_variable::{TypeVariableOrigin};
9595
use rustc::middle::region;
96-
use rustc::middle::lang_items::TerminationTraitLangItem;
9796
use rustc::ty::subst::{Kind, Subst, Substs};
9897
use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode};
9998
use rustc::ty::{ParamTy, LvaluePreference, NoPreference, PreferMutLvalue};
@@ -1066,24 +1065,25 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
10661065
}
10671066
fcx.demand_suptype(span, ret_ty, actual_return_ty);
10681067

1069-
// If the termination trait language item is activated, check that the main return type
1070-
// implements the termination trait.
1071-
if fcx.tcx.lang_items().termination().is_some() {
1072-
if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() {
1073-
if id == fn_id {
1074-
match fcx.sess().entry_type.get() {
1075-
Some(config::EntryMain) => {
1076-
let term_id = fcx.tcx.require_lang_item(TerminationTraitLangItem);
1077-
1078-
let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty)));
1079-
let trait_ref = ty::TraitRef::new(term_id, substs);
1080-
let cause = traits::ObligationCause::new(
1081-
span, fn_id, ObligationCauseCode::MainFunctionType);
1082-
1083-
inherited.register_predicate(
1084-
traits::Obligation::new(cause, param_env, trait_ref.to_predicate()));
1085-
},
1086-
_ => {},
1068+
if fcx.tcx.sess.features.borrow().termination_trait {
1069+
// If the termination trait language item is activated, check that the main return type
1070+
// implements the termination trait.
1071+
if let Some(term_id) = fcx.tcx.lang_items().termination() {
1072+
if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() {
1073+
if id == fn_id {
1074+
match fcx.sess().entry_type.get() {
1075+
Some(config::EntryMain) => {
1076+
let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty)));
1077+
let trait_ref = ty::TraitRef::new(term_id, substs);
1078+
let cause = traits::ObligationCause::new(
1079+
span, fn_id, ObligationCauseCode::MainFunctionType);
1080+
1081+
inherited.register_predicate(
1082+
traits::Obligation::new(
1083+
cause, param_env, trait_ref.to_predicate()));
1084+
},
1085+
_ => {},
1086+
}
10871087
}
10881088
}
10891089
}

src/librustc_typeck/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
203203
}
204204

205205
let actual = tcx.fn_sig(main_def_id);
206-
let expected_return_type = if tcx.lang_items().termination().is_some() {
206+
let expected_return_type = if tcx.lang_items().termination().is_some()
207+
&& tcx.sess.features.borrow().termination_trait {
207208
// we take the return type of the given main function, the real check is done
208209
// in `check_fn`
209210
actual.output().skip_binder()

src/libstd/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ pub mod rt;
503503
// The trait to support returning arbitrary types in the main function
504504
mod termination;
505505

506-
#[unstable(feature = "termination_trait", issue = "0")]
506+
#[unstable(feature = "termination_trait", issue = "43301")]
507507
pub use self::termination::Termination;
508508

509509
// Include a number of private modules that exist solely to provide

src/libstd/termination.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use libc;
2020
/// The default implementations are returning `libc::EXIT_SUCCESS` to indicate
2121
/// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned.
2222
#[cfg_attr(not(stage0), lang = "termination")]
23-
#[unstable(feature = "termination_trait", issue = "0")]
23+
#[unstable(feature = "termination_trait", issue = "43301")]
2424
#[rustc_on_unimplemented =
2525
"`main` can only return types that implement {Termination}, not `{Self}`"]
2626
pub trait Termination {
@@ -29,12 +29,12 @@ pub trait Termination {
2929
fn report(self) -> i32;
3030
}
3131

32-
#[unstable(feature = "termination_trait", issue = "0")]
32+
#[unstable(feature = "termination_trait", issue = "43301")]
3333
impl Termination for () {
3434
fn report(self) -> i32 { libc::EXIT_SUCCESS }
3535
}
3636

37-
#[unstable(feature = "termination_trait", issue = "0")]
37+
#[unstable(feature = "termination_trait", issue = "43301")]
3838
impl<T: Termination, E: Error> Termination for Result<T, E> {
3939
fn report(self) -> i32 {
4040
match self {
@@ -47,7 +47,7 @@ impl<T: Termination, E: Error> Termination for Result<T, E> {
4747
}
4848
}
4949

50-
#[unstable(feature = "termination_trait", issue = "0")]
50+
#[unstable(feature = "termination_trait", issue = "43301")]
5151
fn print_error<E: Error>(err: E) {
5252
eprintln!("Error: {}", err.description());
5353

@@ -56,19 +56,19 @@ fn print_error<E: Error>(err: E) {
5656
}
5757
}
5858

59-
#[unstable(feature = "termination_trait", issue = "0")]
59+
#[unstable(feature = "termination_trait", issue = "43301")]
6060
impl Termination for ! {
6161
fn report(self) -> i32 { unreachable!(); }
6262
}
6363

64-
#[unstable(feature = "termination_trait", issue = "0")]
64+
#[unstable(feature = "termination_trait", issue = "43301")]
6565
impl Termination for bool {
6666
fn report(self) -> i32 {
6767
if self { libc::EXIT_SUCCESS } else { libc::EXIT_FAILURE }
6868
}
6969
}
7070

71-
#[unstable(feature = "termination_trait", issue = "0")]
71+
#[unstable(feature = "termination_trait", issue = "43301")]
7272
impl Termination for i32 {
7373
fn report(self) -> i32 {
7474
self

src/libsyntax/feature_gate.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,9 @@ declare_features! (
444444

445445
// Nested `impl Trait`
446446
(active, nested_impl_trait, "1.24.0", Some(34511)),
447+
448+
// Termination trait in main (RFC 1937)
449+
(active, termination_trait, "1.24.0", Some(43301)),
447450
);
448451

449452
declare_features! (
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() -> i32 { //~ ERROR main function has wrong type [E0580]
12+
0
13+
}

src/test/compile-fail/termination-trait-not-satisfied.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(termination_trait)]
12+
1113
struct ReturnType {}
1214

1315
fn main() -> ReturnType { //~ ERROR `ReturnType: std::Termination` is not satisfied

0 commit comments

Comments
 (0)