Make diagnostic for unsatisfied Termination bounds more precise
This commit is contained in:
parent
bf286a82e2
commit
684df4d24e
@ -451,6 +451,7 @@
|
||||
call_once,
|
||||
caller_location,
|
||||
capture_disjoint_fields,
|
||||
cause,
|
||||
cdylib,
|
||||
ceilf32,
|
||||
ceilf64,
|
||||
|
@ -164,6 +164,10 @@ fn on_unimplemented_note(
|
||||
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.
|
||||
ty::print::with_no_trimmed_paths!({
|
||||
let generics = self.tcx.generics_of(def_id);
|
||||
|
@ -2154,8 +2154,16 @@ pub fn id() -> u32 {
|
||||
#[cfg_attr(not(test), lang = "termination")]
|
||||
#[stable(feature = "termination_trait_lib", since = "1.61.0")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "`main` has invalid return type `{Self}`",
|
||||
label = "`main` can only return types that implement `{Termination}`"
|
||||
on(
|
||||
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 {
|
||||
/// 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
|
||||
|
|
||||
LL | #[test]
|
||||
@ -6,9 +6,8 @@ LL | #[test]
|
||||
LL | / fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> {
|
||||
LL | | "0".parse()
|
||||
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 by a bound in `assert_test_result`
|
||||
--> $SRC_DIR/test/src/lib.rs:LL:COL
|
||||
|
Loading…
Reference in New Issue
Block a user