From 3070f394629ae8c6463269247ea0cb223d5328f1 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 14 May 2018 23:25:22 +0100 Subject: [PATCH 1/5] Stabilise inclusive_range_methods --- src/liballoc/tests/lib.rs | 1 - src/libcore/ops/range.rs | 13 +++---------- src/libcore/tests/lib.rs | 1 - src/librustc/lib.rs | 1 - src/librustc_mir/lib.rs | 1 - src/librustc_target/lib.rs | 1 - src/librustc_trans/lib.rs | 1 - 7 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 1c8ff316e55aa..081c473768f1f 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -25,7 +25,6 @@ #![feature(try_reserve)] #![feature(unboxed_closures)] #![feature(exact_chunks)] -#![feature(inclusive_range_methods)] extern crate alloc_system; extern crate core; diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index b01a769eda7fd..28707f8aa05df 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -318,8 +318,6 @@ impl> RangeTo { /// # Examples /// /// ``` -/// #![feature(inclusive_range_methods)] -/// /// assert_eq!((3..=5), std::ops::RangeInclusive::new(3, 5)); /// assert_eq!(3 + 4 + 5, (3..=5).sum()); /// @@ -355,12 +353,11 @@ impl RangeInclusive { /// # Examples /// /// ``` - /// #![feature(inclusive_range_methods)] /// use std::ops::RangeInclusive; /// /// assert_eq!(3..=5, RangeInclusive::new(3, 5)); /// ``` - #[unstable(feature = "inclusive_range_methods", issue = "49022")] + #[stable(feature = "inclusive_range_methods", since = "1.27.0")] #[inline] pub const fn new(start: Idx, end: Idx) -> Self { Self { start, end } @@ -379,11 +376,9 @@ impl RangeInclusive { /// # Examples /// /// ``` - /// #![feature(inclusive_range_methods)] - /// /// assert_eq!((3..=5).start(), &3); /// ``` - #[unstable(feature = "inclusive_range_methods", issue = "49022")] + #[stable(feature = "inclusive_range_methods", since = "1.27.0")] #[inline] pub fn start(&self) -> &Idx { &self.start @@ -402,11 +397,9 @@ impl RangeInclusive { /// # Examples /// /// ``` - /// #![feature(inclusive_range_methods)] - /// /// assert_eq!((3..=5).end(), &5); /// ``` - #[unstable(feature = "inclusive_range_methods", issue = "49022")] + #[stable(feature = "inclusive_range_methods", since = "1.27.0")] #[inline] pub fn end(&self) -> &Idx { &self.end diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 5e98e40e0d5e6..3f1a155f3b0ca 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -44,7 +44,6 @@ #![feature(exact_chunks)] #![cfg_attr(stage0, feature(atomic_nand))] #![feature(reverse_bits)] -#![feature(inclusive_range_methods)] #![feature(iterator_find_map)] #![feature(slice_internals)] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 879d38c489443..ea3df2727c675 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -69,7 +69,6 @@ #![feature(trusted_len)] #![feature(catch_expr)] #![feature(test)] -#![feature(inclusive_range_methods)] #![recursion_limit="512"] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 2545ba3a94af1..46052519ad43c 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -31,7 +31,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(range_contains)] #![feature(rustc_diagnostic_macros)] #![feature(nonzero)] -#![feature(inclusive_range_methods)] #![feature(crate_visibility_modifier)] #![feature(never_type)] #![feature(specialization)] diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index 45f2ee13bbdc9..8f4911574398b 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -29,7 +29,6 @@ #![feature(const_fn)] #![feature(fs_read_write)] #![feature(inclusive_range)] -#![feature(inclusive_range_methods)] #![feature(slice_patterns)] #[macro_use] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 537dfc61b2a4f..96db59cbede7f 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -29,7 +29,6 @@ #![feature(rustc_diagnostic_macros)] #![feature(slice_sort_by_cached_key)] #![feature(optin_builtin_traits)] -#![feature(inclusive_range_methods)] use rustc::dep_graph::WorkProduct; use syntax_pos::symbol::Symbol; From cf2b1c1b3eded5d6d8f84e52bc9eccad051dd5bf Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 14 May 2018 23:31:20 +0100 Subject: [PATCH 2/5] Stabilise into_inner --- src/libcore/ops/range.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 28707f8aa05df..2664e18a93cc0 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -404,6 +404,19 @@ impl RangeInclusive { pub fn end(&self) -> &Idx { &self.end } + + /// Destructures the RangeInclusive into (lower bound, upper (inclusive) bound). + /// + /// # Examples + /// + /// ``` + /// assert_eq!((3..=5).into_inner(), (3, 5)); + /// ``` + #[stable(feature = "inclusive_range_methods", since = "1.27.0")] + #[inline] + pub fn into_inner(self) -> (Idx, Idx) { + (self.start, self.end) + } } #[stable(feature = "inclusive_range", since = "1.26.0")] From 2d1afbd6b09e0b7418dfeeccd2236d715e96c14f Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 16 May 2018 21:19:17 +0100 Subject: [PATCH 3/5] Add doc comments mentioning unspecified behaviour upon exhaustion --- src/libcore/ops/range.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 2664e18a93cc0..e542f5f60fcfa 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -370,6 +370,9 @@ impl RangeInclusive { /// whether the inclusive range is empty, use the [`is_empty()`] method /// instead of comparing `start() > end()`. /// + /// Note: the value returned by this method is unspecified after the range + /// has been iterated to exhaustion. + /// /// [`end()`]: #method.end /// [`is_empty()`]: #method.is_empty /// @@ -391,6 +394,9 @@ impl RangeInclusive { /// whether the inclusive range is empty, use the [`is_empty()`] method /// instead of comparing `start() > end()`. /// + /// Note: the value returned by this method is unspecified after the range + /// has been iterated to exhaustion. + /// /// [`start()`]: #method.start /// [`is_empty()`]: #method.is_empty /// @@ -405,7 +411,10 @@ impl RangeInclusive { &self.end } - /// Destructures the RangeInclusive into (lower bound, upper (inclusive) bound). + /// Destructures the `RangeInclusive` into (lower bound, upper (inclusive) bound). + /// + /// Note: the value returned by this method is unspecified after the range + /// has been iterated to exhaustion. /// /// # Examples /// From b48588726eeb35c79ad7a09dc74732f16bef5253 Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Fri, 11 May 2018 11:29:04 -0300 Subject: [PATCH 4/5] Fix `fn main() -> impl Trait` for non-`Termination` trait Fixes #50595. This bug currently affects stable. Why I think we can go for hard error: - It will in stable for at most one cycle and there is no legitimate reason to abuse it, nor any known uses in the wild. - It only affects `bin` crates (which have a `main`), so there is little practical difference between a hard error or a deny lint, both are a one line fix. The fix was to just unshadow a variable. Thanks @nikomatsakis for the mentoring! r? @nikomatsakis --- src/librustc_typeck/check/mod.rs | 8 ++++---- .../termination-trait-for-impl-termination.rs | 13 +++++++++++++ .../termination-trait-impl-trait.rs | 13 +++++++++++++ .../termination-trait-impl-trait.stderr | 11 +++++++++++ 4 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs create mode 100644 src/test/ui/rfc-1937-termination-trait/termination-trait-impl-trait.rs create mode 100644 src/test/ui/rfc-1937-termination-trait/termination-trait-impl-trait.stderr diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 044509c868840..81e6efc7898b5 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1038,11 +1038,11 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, let ret_ty = fn_sig.output(); fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::SizedReturnType); - let ret_ty = fcx.instantiate_anon_types_from_return_value(fn_id, &ret_ty); - fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty))); + let revealed_ret_ty = fcx.instantiate_anon_types_from_return_value(fn_id, &ret_ty); + fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty))); fn_sig = fcx.tcx.mk_fn_sig( fn_sig.inputs().iter().cloned(), - ret_ty, + revealed_ret_ty, fn_sig.variadic, fn_sig.unsafety, fn_sig.abi @@ -1124,7 +1124,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, actual_return_ty = fcx.next_diverging_ty_var( TypeVariableOrigin::DivergingFn(span)); } - fcx.demand_suptype(span, ret_ty, actual_return_ty); + fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty); // Check that the main return type implements the termination trait. if let Some(term_id) = fcx.tcx.lang_items().termination() { diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs new file mode 100644 index 0000000000000..5bce3f8045eeb --- /dev/null +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs @@ -0,0 +1,13 @@ +// Copyright 2018 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(termination_trait_lib)] + +fn main() -> impl std::process::Termination { } diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-impl-trait.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-impl-trait.rs new file mode 100644 index 0000000000000..92d21864c7483 --- /dev/null +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-impl-trait.rs @@ -0,0 +1,13 @@ +// Copyright 2018 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Tests that an `impl Trait` that is not `impl Termination` will not work. +fn main() -> impl Copy { } +//~^ ERROR `main` has invalid return type `impl std::marker::Copy` diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-impl-trait.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-impl-trait.stderr new file mode 100644 index 0000000000000..7485f3066bb27 --- /dev/null +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-impl-trait.stderr @@ -0,0 +1,11 @@ +error[E0277]: `main` has invalid return type `impl std::marker::Copy` + --> $DIR/termination-trait-impl-trait.rs:12:14 + | +LL | fn main() -> impl Copy { } + | ^^^^^^^^^ `main` can only return types that implement `std::process::Termination` + | + = help: consider using `()`, or a `Result` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From c05689b04e1d1947e7cdcc80243dcd84badb65cb Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Tue, 15 May 2018 15:42:41 -0300 Subject: [PATCH 5/5] Rename ret_ty to declared_ret_ty --- src/librustc_typeck/check/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 81e6efc7898b5..61c1bdb7110e5 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1036,9 +1036,9 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, let mut fcx = FnCtxt::new(inherited, param_env, body.value.id); *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id); - let ret_ty = fn_sig.output(); - fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::SizedReturnType); - let revealed_ret_ty = fcx.instantiate_anon_types_from_return_value(fn_id, &ret_ty); + let declared_ret_ty = fn_sig.output(); + fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType); + let revealed_ret_ty = fcx.instantiate_anon_types_from_return_value(fn_id, &declared_ret_ty); fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty))); fn_sig = fcx.tcx.mk_fn_sig( fn_sig.inputs().iter().cloned(), @@ -1132,7 +1132,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, if id == fn_id { match entry_type { config::EntryMain => { - let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty))); + let substs = fcx.tcx.mk_substs(iter::once(Kind::from(declared_ret_ty))); let trait_ref = ty::TraitRef::new(term_id, substs); let return_ty_span = decl.output.span(); let cause = traits::ObligationCause::new(