think about a opaque type in return position, if the hidden type for the opaque type is totally inferred by the rust compiler, then why we need to specify the lifetime variable that the hidden type may use? is it possible that compiler may infer two different hidden type for the same function?
If it was inferred, it could change unexpectedly and break the callers.
can you help providing a example?
pub trait Processor {
fn process(&self);
}
pub fn new_processor() -> impl Processor {
// some code to return a type which implement Processor
}
fn main() {
let b = new_processor();
// we can only invoke process method
b.process();
}
i think no matter how we try to implement function new_processor, b.process() will always work.
No. Because opaque types are not allowed in let
assignments and Processor
does not define a method talk()
.
With correct code, your example works fine:
... even when you use the opaque type on the fly:
sorry for the error, i correct my sample code. then in the sample code, b.process() will never break no matter how we implement new_processor. and the question still exist, why we need to specify the lifetime variable for opaque type in return position.
Where in your or my working examples did we specify lifetime variables for a RPIT?
You may want to refer to this blog post. TL;DR: In editions before 2024, -> impl Trait
outside of traits only capture lifetimes that are mentioned in the return. In edition 2024, they'll always capture lifetimes, unless you opt out via precise capturing. So in edition 2024 -- which drops in about a week -- the answer to your OP is "you don't need to specify the lifetime".
Whether the lifetime is captured or not changes how borrow checking works. See this thread for an example of that being an issue.[1]
In many ways you have the freedom to change the implementation without breaking downstream so long as you don't change the signature. However, opaque return types leak auto-traits like Send
and Sync
. If your changes causes the return to lose an auto-trait, that's a breaking change.
(Downstream can also figure out other things about your return type, such as its size, alignment, and even TypeId
when 'static
. But it's generally not considered breaking to change these things.)
That particular example is for an opaque return in a trait, which always captures lifetimes (on all editions) and doesn't yet support precise capturing. âŠī¸