How to get the infor of where exactly a trait restriction comes from?

With kube-rs v3.0.0 and gateway-api, I got an error in my code:

error[E0277]: the trait bound `gateway_api::gateways::Gateway: k8s_openapi::Metadata` is not satisfied
   --> src/helpers.rs:114:34
    |
114 |     let gateways: Api<Gateway> = Api::namespaced(client, namespace);
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `k8s_openapi::Metadata` is not implemented for `gateway_api::gateways::Gateway`
    |
    = help: the following other types implement trait `k8s_openapi::Metadata`:
              APIService
              Binding
              CSIDriver
              CSINode
              CSIStorageCapacity
              CertificateSigningRequest
              ClusterRole
              ClusterRoleBinding
            and 77 others
    = note: required for `gateway_api::gateways::Gateway` to implement `kube::Resource`

Seems like easy to understand, that the lib should impl Metadata for Gateway. But looking through Resource and Api::namespaced, I could not find the place where Metadata is required.

Api::namespaced does not require Metadata.

impl<K: Resource> Api<K>
where
    <K as Resource>::DynamicType: Default,
{
  fn namespaced(client: Client, ns: &str) -> Self
    where
        K: Resource<Scope = NamespaceResourceScope>
}

Resource and impl Resource for Gateway does not require Metadata, as far as I can see.

So is there a tool or anything to help me figuring this out?

The compiler, perhaps over-ambitiously, sees that kube::Resource has a blanket implementation for K: k8s_openapi::Metadata + k8s_openapi::Resource and assumes that telling you to satisfy it is useful. The original trait requirement that is not satisfied is tucked away in the last line of the diagnostic: “note: required for gateway_api::gateways::Gateway to implement kube::Resource”.

kube can suppress this indirect explanation, if desired, by adding a #[diagnostic::do_not_recommend] attribute to the impl.

1 Like

I saw the last line. But what is "required" for Gateway to impl Resource? I think it is Metadata. Since Gateway already impls Resource, I am struggling to see why it asks for Metadata.

I am not sure about the blanket impl. As far as I understand, if it was because of that, it would be even weirder.

Just tried about the blanket impl. I cloned gateway-api source and impl Metadata for Gateway. I got compile error, that after my impl, the blanket impl kicked in and conflicts with Resource already impled for Gateway.

Be careful; kube::Resource and k8s_openapi::Resource are two different traits. Make sure you are not confusing them with each other, and specify which one you mean when talking about them.

1 Like