I have a snippet of code similar to this in my code base, after I made changes to upgrade to a more recent version of wasm-tools: ```rust pub(crate) struct JoinVisitor<L, R>(pub(crate) L, pub(crate) R); macro_rules! join_visit { ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => { $(fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output { (self.0.$visit($($($arg.clone()),*)?), self.1.$visit($($($arg),*)?)) })* } } impl<'a, L, R> wasmparser::VisitOperator<'a> for JoinVisitor<L, R> where L: wasmparser::VisitOperator<'a>, R: wasmparser::VisitOperator<'a>, { type Output = (L::Output, R::Output); wasmparser::for_each_visit_operator!(join_visit); } impl<'a, L, R> wasmparser::VisitSimdOperator<'a> for JoinVisitor<L, R> where L: wasmparser::VisitSimdOperator<'a>, R: wasmparser::VisitSimdOperator<'a>, { wasmparser::for_each_visit_simd_operator!(join_visit); } ``` But currently this seems to still fail to visit SIMD opcodes if I'm calling `JoinVisitor::visit_operator`. From the looks of it that's because there is a new function I need to implement `VisitOperator::simd_visitor`. However I cannot implement this method in a generic-preserving way. If I do the naive thing ```rust impl<'a, L, R> VisitOperator<'a> for JoinVisitor<L, R> where L: VisitOperator<'a> + VisitSimdOperator<'a>, R: VisitOperator<'a> + VisitSimdOperator<'a>, { fn simd_visitor(&mut self) -> Option<...> { Some(self) } } ``` then I will have this code build, but the `JoinVisitor: VisitOperator` will now require an implementation of `VisitSimdOperator`. As far as I can tell there is no way to construct this such a way that `simd_visitor` returns `Some` only if `L + R: VisitSimdOperator`. An obvious ```rust fn simd_visitor( &mut self, ) -> Option<&mut dyn wasmparser::VisitSimdOperator<'a, Output = Self::Output>> where L: wasmparser::VisitSimdOperator<'a>, R: wasmparser::VisitSimdOperator<'a>, { Some(self) } ``` won't work because this method has stricter requirements than the trait being `impl`d, nor will this: ```rust fn simd_visitor( &mut self, ) -> Option<&mut dyn wasmparser::VisitSimdOperator<'a, Output = Self::Output>> { Some(JoinVisitor(self.0.simd_visitor()?, self.1.simd_visitor()?)) } ``` due to the signature requiring `&mut dyn VisitSimdOperator` to be returned. Besides this particular snag, `simd_visitor` is also a plain footgun in that implementing a `VisitSimdOperator` is not all that's required on each of the implementors to support visiting SIMD operators, and the failure mode is a *runtime* error. --- In the world where we know we'll only have `VisitOperator` and `VisitSimdOperator` this could be addressed by adding `visit_operator` to `VisitSimdOperator` as well (which would delegate to its supertrait's `visit_operator` if it isn't a SIMD opcode,) but that won't work out nicely if future delivers another `Visit*Operator` that's unrelated to `VisitSimdOperator`. The only other way to address this that I can see is to add a new associated type to `VisitOperator` along the lines of `type SimdVisitor` that `simd_visitor` would return. Defaulting to `Infallible` or something.