Undefine a trait method

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.)

1 Like

Fantastic, thanks! We implemented this with a private struct

struct this_method_cannot_be_called_use_successors_instead;

and a bound

for<'a> this_method_cannot_be_called_use_successors_instead: Clone,

which comes out very nicely when compiling.

1 Like

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.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.