Why isn't `Termination` in `core`?


#1

Brought to my attention here, in the custom test frameworks eRFC, it was mentioned that !#[no_std] crates use #![no_main] to avoid the Termination trait lang item.

Is there any reason Termination isn’t provided in core? It seems like something that would be useful for those no_std cases that can use the default main entry point, at least.


#2

Would it be because Termination is designed so you can give the OS a return code? If you’re writing no_std code then a lot of the time there isn’t an OS to return to, so the Termination trait might not make sense.


#3

I understand his point is that even for !#[no_std] programs, in cfg(test) people still need Termination. So if not for start, at least for #[test] Termination should be included in core.


#4

If it can be in core, it should be.


#5

I think the reason it’s in std is that it could plausible want to return not i32 but a platform-specific exit code struct (thanks, plan 9), and thus fits more naturally with the other platform-specific process-related things in std.

Also, I thought it was normal to explicitly exclude no_std from test? I just do things like


#6

He wants “custom test framework” with no_std. So this is not a solution…

So the bottom line would be: should a “custom test framework” be able to define their own Termination?


#7

I would have expected that the test framework would be in control of the entry point and thus could use or not care about Termination at will.


#8

That seems silly… just make the return type be an associated type that defaults to i32, and require that on “normal” targets, main returns Termination<Return = i32>.


#9

We could still include the Termination trait in core, and then put platform-specific instances of that trait into std or similar.


#10

@josh the problem is that Termination::report encodes a platform specific representation of how an application reports its final status. A very widely applicable representation since it’s encoded in the C standard for any “hosted environment”, but still not required for all environments that Rust code may run in.


#11

How about the following:

pub trait Termination {
    type ResultCode;
    const EXIT_SUCCESS: Self::ResultCode;
    fn report(self) -> Self::ResultCode;
}

#12

This is unstable atm; however, I have written an RFC about it:


#13

I’m aware. I’m running on the assumption that we’ll get this feature in some form eventually.