We are in a situation where trait B extends trait A, but its semantics is more specialized, so we would like to have for trait B a different method naming than for trait A: playground.
The new method just delegates to trait A, so users of B will get A's implementation, but to avoid confusion we want users to be unable to call the old method. They are prevented from doing so initially by ambiguity, then by deprecation, and finally by the fact that the overridden method will throw a panic.
But, it there a clean way to keep user statically, at compile time, from calling the deprecated method?
There's an unimplemented RFC around trivial bounds that would let you add where clauses which are unsatisfiable, making the method impossible to call without being an error to define.
There's a hack/workaround for trivial bounds which isn't always applicable, but is at least applicable to your playground: adding a higher-ranked where clause which is checked at the call-site and not the definition. For example:
trait B: A {
// trivially unsatisfiable bound
// vvvvvvvvvvvvvvvvvvvvvvvv
fn generic(&self) where for<'a> str: Sized {
unimplemented!();
}
}
fn test2(b: impl B) {
// B::generic(&b); // Now an error
}
Scroll down a little here for more tangential ranting. If the refinement feature ever stops requiring explicit opt-in, that may be a threat to this hack/workaround. (Personally, for that reason, I would consider it a breaking change.)
Hard to tell from your example, but to me this sounds like trying to do OOP/inheritance in Rust, and running head first into the fact that inheritance doesn't actually match the real world.
If that reading is correct you should consider a redesign using more rust-native design patterns.