Rollup merge of #103142 - fmease:fix-103052, r=oli-obk
Make diagnostic for unsatisfied `Termination` bounds more precise Don't blindly emit a diagnostic claiming that “*`main` has an invalid return type*” if we encounter a type that should but doesn't implement `std::process::Termination` and isn't actually the return type of the program entry `main`. Fixes #103052. ``@rustbot`` label A-diagnostics T-compiler T-libs r? diagnostics
This commit is contained in:
commit
472a8742a6
@ -451,6 +451,7 @@ symbols! {
|
|||||||
call_once,
|
call_once,
|
||||||
caller_location,
|
caller_location,
|
||||||
capture_disjoint_fields,
|
capture_disjoint_fields,
|
||||||
|
cause,
|
||||||
cdylib,
|
cdylib,
|
||||||
ceilf32,
|
ceilf32,
|
||||||
ceilf64,
|
ceilf64,
|
||||||
|
@ -164,6 +164,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||||||
flags.push((sym::from_desugaring, Some(format!("{:?}", k))));
|
flags.push((sym::from_desugaring, Some(format!("{:?}", k))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let ObligationCauseCode::MainFunctionType = obligation.cause.code() {
|
||||||
|
flags.push((sym::cause, Some("MainFunctionType".to_string())));
|
||||||
|
}
|
||||||
|
|
||||||
// Add all types without trimmed paths.
|
// Add all types without trimmed paths.
|
||||||
ty::print::with_no_trimmed_paths!({
|
ty::print::with_no_trimmed_paths!({
|
||||||
let generics = self.tcx.generics_of(def_id);
|
let generics = self.tcx.generics_of(def_id);
|
||||||
|
@ -2154,8 +2154,16 @@ pub fn id() -> u32 {
|
|||||||
#[cfg_attr(not(test), lang = "termination")]
|
#[cfg_attr(not(test), lang = "termination")]
|
||||||
#[stable(feature = "termination_trait_lib", since = "1.61.0")]
|
#[stable(feature = "termination_trait_lib", since = "1.61.0")]
|
||||||
#[rustc_on_unimplemented(
|
#[rustc_on_unimplemented(
|
||||||
message = "`main` has invalid return type `{Self}`",
|
on(
|
||||||
label = "`main` can only return types that implement `{Termination}`"
|
all(not(bootstrap), cause = "MainFunctionType"),
|
||||||
|
message = "`main` has invalid return type `{Self}`",
|
||||||
|
label = "`main` can only return types that implement `{Termination}`"
|
||||||
|
),
|
||||||
|
on(
|
||||||
|
bootstrap,
|
||||||
|
message = "`main` has invalid return type `{Self}`",
|
||||||
|
label = "`main` can only return types that implement `{Termination}`"
|
||||||
|
)
|
||||||
)]
|
)]
|
||||||
pub trait Termination {
|
pub trait Termination {
|
||||||
/// Is called to get the representation of the value as status code.
|
/// Is called to get the representation of the value as status code.
|
||||||
|
11
src/test/ui/rfc-1937-termination-trait/issue-103052-1.rs
Normal file
11
src/test/ui/rfc-1937-termination-trait/issue-103052-1.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Check that we don't blindly emit a diagnostic claiming that "`main` has an invalid return type"
|
||||||
|
// if we encounter a type that doesn't implement `std::process::Termination` and is not actually
|
||||||
|
// the return type of the program entry `main`.
|
||||||
|
|
||||||
|
fn receive(_: impl std::process::Termination) {}
|
||||||
|
|
||||||
|
struct Something;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
receive(Something); //~ ERROR the trait bound `Something: Termination` is not satisfied
|
||||||
|
}
|
17
src/test/ui/rfc-1937-termination-trait/issue-103052-1.stderr
Normal file
17
src/test/ui/rfc-1937-termination-trait/issue-103052-1.stderr
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
error[E0277]: the trait bound `Something: Termination` is not satisfied
|
||||||
|
--> $DIR/issue-103052-1.rs:10:13
|
||||||
|
|
|
||||||
|
LL | receive(Something);
|
||||||
|
| ------- ^^^^^^^^^ the trait `Termination` is not implemented for `Something`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
note: required by a bound in `receive`
|
||||||
|
--> $DIR/issue-103052-1.rs:5:20
|
||||||
|
|
|
||||||
|
LL | fn receive(_: impl std::process::Termination) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `receive`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
18
src/test/ui/rfc-1937-termination-trait/issue-103052-2.rs
Normal file
18
src/test/ui/rfc-1937-termination-trait/issue-103052-2.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#![feature(return_position_impl_trait_in_trait)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
mod child {
|
||||||
|
trait Main {
|
||||||
|
fn main() -> impl std::process::Termination;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Something;
|
||||||
|
|
||||||
|
impl Main for () {
|
||||||
|
fn main() -> Something { //~ ERROR the trait bound `Something: Termination` is not satisfied
|
||||||
|
Something
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
15
src/test/ui/rfc-1937-termination-trait/issue-103052-2.stderr
Normal file
15
src/test/ui/rfc-1937-termination-trait/issue-103052-2.stderr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
error[E0277]: the trait bound `Something: Termination` is not satisfied
|
||||||
|
--> $DIR/issue-103052-2.rs:12:22
|
||||||
|
|
|
||||||
|
LL | fn main() -> Something {
|
||||||
|
| ^^^^^^^^^ the trait `Termination` is not implemented for `Something`
|
||||||
|
|
|
||||||
|
note: required by a bound in `Main::main::{opaque#0}`
|
||||||
|
--> $DIR/issue-103052-2.rs:6:27
|
||||||
|
|
|
||||||
|
LL | fn main() -> impl std::process::Termination;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::main::{opaque#0}`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
@ -1,4 +1,4 @@
|
|||||||
error[E0277]: `main` has invalid return type `f32`
|
error[E0277]: the trait bound `f32: Termination` is not satisfied
|
||||||
--> $DIR/termination-trait-test-wrong-type.rs:6:1
|
--> $DIR/termination-trait-test-wrong-type.rs:6:1
|
||||||
|
|
|
|
||||||
LL | #[test]
|
LL | #[test]
|
||||||
@ -6,9 +6,8 @@ LL | #[test]
|
|||||||
LL | / fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> {
|
LL | / fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> {
|
||||||
LL | | "0".parse()
|
LL | | "0".parse()
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_^ `main` can only return types that implement `Termination`
|
| |_^ the trait `Termination` is not implemented for `f32`
|
||||||
|
|
|
|
||||||
= help: the trait `Termination` is not implemented for `f32`
|
|
||||||
= note: required for `Result<f32, ParseFloatError>` to implement `Termination`
|
= note: required for `Result<f32, ParseFloatError>` to implement `Termination`
|
||||||
note: required by a bound in `assert_test_result`
|
note: required by a bound in `assert_test_result`
|
||||||
--> $SRC_DIR/test/src/lib.rs:LL:COL
|
--> $SRC_DIR/test/src/lib.rs:LL:COL
|
||||||
|
Loading…
x
Reference in New Issue
Block a user