Re:C23 is finished: Here is what is on the menu
by steveklabnik on Friday August 05, 2022 @08:58PM
(#32363749)
Rust breaks parametricity via functions like size_of and in unstable features such as specialization.
In C++ there are literally three separate implementations of std::string's contains method for three type signatures. This is pretty clearly what is being discussed as "acting in a different way".
In Rust there's just one, here's the entire function body of contains: pat.is_contained_in(self)
OK, well that's just buck passing right? Clearly this is_contained_in() method on Pattern is really just the contains() implementation, we're passing the work to this function that as you point out needs to be implemented by each of the matching types for Pattern.
Except, wait, Pattern actually defines is_contained_in(haystack), thus: self.into_searcher(haystack).next_match().is_some()
Sure enough Pattern implementations although they're not forbidden from implementing is_contained_in themselves, do not in fact do that, they just implement into_searcher. Our hypothetical Jpeg type can provide a suitable into_searcher implementation which results in a Searcher for the Jpeg somehow, without knowing what contains() or split_once() or trim_start_matches() do, and now they will work on Jpegs.
So the "acting in a different way for each type" for contains() ends up only being because of details about the inner behaviour of that type, which is exactly parametric polymorphism so far as I can see.