diff options
| author | leonardo.yvens <leoyvens@gmail.com> | 2018-05-11 11:29:04 -0300 |
|---|---|---|
| committer | leonardo.yvens <leoyvens@gmail.com> | 2018-05-11 11:29:04 -0300 |
| commit | 587566eda71847b5cd57bfb91b677f7dac653528 (patch) | |
| tree | 6f5221893144087e003b926636108fdd47d8a236 | |
| parent | e5f80f2a4f016bf724a1cfb580619d71c8fd39ec (diff) | |
| download | rust-587566eda71847b5cd57bfb91b677f7dac653528.tar.gz rust-587566eda71847b5cd57bfb91b677f7dac653528.zip | |
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
4 files changed, 41 insertions, 4 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index db859e42057..f513b1f23ad 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 00000000000..5bce3f8045e --- /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 <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. + +#![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 00000000000..92d21864c74 --- /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 <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. + +// 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 00000000000..7485f3066bb --- /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`. |
