Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get error about missing "tracing" dependency when trying to use #[component] macro #2156

Closed
DanielJoyce opened this issue Jan 2, 2024 · 20 comments
Labels
bug Something isn't working
Milestone

Comments

@DanielJoyce
Copy link

Describe the bug
When using the component attribute macro, get an error saying tracing is a missing dependency.

failed to resolve: use of undeclared crate or module `tracing`
use of undeclared crate or module `tracing`rustc[Click for full compiler diagnostic]

Leptos Dependencies

[dependencies]
leptos = "0.5.4"
axum = "0.7.2"
leptos_axum = "0.5.4"

To Reproduce
Steps to reproduce the behavior:

  1. Create a component
  2. Add the macro
  3. See red squiggle

Expected behavior
According to the docs, component macro shouldn't require tracing crate.

Screenshots
image

Additional context

enabling the tracing feature for leptos does not fix it

[dependencies]
leptos = { version = "0.5.4", features = ["tracing"] }
axum = "0.7.2"
leptos_axum = "0.5.4"

The view function in lib.rs seems to have a direct dependency on tracing that is not feature gated?

image

Adding tracing as a direct dependency to the cargo.toml fixes the issue

[dependencies]
leptos = "0.5.4"
axum = "0.7.2"
leptos_axum = "0.5.4"
tracing = "0.1.40"
@gbj
Copy link
Collaborator

gbj commented Jan 2, 2024

I'm sorry, I can't reproduce the issue by starting with one of our starters and removing the tracing dependency. Could you please provide a reproduction, i.e., a minimal GitHub repo, or a complete Cargo.toml and example code. (Please copy and paste rather than screenshotting.)

(And just checking: When you say "see red squiggle," is this just in rust-analyzer or are you getting an error while building, and what is the error?)

@DanielJoyce
Copy link
Author

The red squiggle is rust-analyzer. I will get up a repro. I didn't use a starter.

@DanielJoyce
Copy link
Author

Ran cargo build, got same error there as well:

error[E0433]: failed to resolve: use of undeclared crate or module `tracing`
 --> src/components/signup.rs:3:1
  |
3 | #[component]
  | ^^^^^^^^^^^^ use of undeclared crate or module `tracing`

@DanielJoyce
Copy link
Author

Upgraded to rust 1.75, build still fails on missing tracing.

@DanielJoyce
Copy link
Author

Okay, apparently the issue is with leptos-axum. Adding it triggers the issue

@DanielJoyce
Copy link
Author

Cargo.toml:

[package]
name = "leptos-bug"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
leptos = "0.5.4"
# Adding leptos-axum causes component to say missing dependnecy on tracing.
leptos_axum = "0.5.4"

main.rs:

use leptos::{component, view, IntoView};

// When leptos-axum crate is added, #[component] macro errors out about missing tracing dependency unless
// tracing is added at top level
// adding tracing as top-level dep, or removing leptos-axum fixes the issue.
#[component]
fn SignupForm() -> impl IntoView {
    view! {
        <div>
            <h1>{"Hello World"}</h1>
        </div>
    }
}

fn main() {
    println!("Hello, world!");
}

@DanielJoyce
Copy link
Author

DanielJoyce commented Jan 5, 2024

Hmm, leptos-axum has a hard dependency on tracing, so I don't know if this something that can be fixed in the features system of cargo?

Looking at the Cargo of leptos_axum,

[package]
name = "leptos_axum"
version = { workspace = true }
edition = "2021"
authors = ["Greg Johnston"]
license = "MIT"
repository = "https://github.com/leptos-rs/leptos"
description = "Axum integrations for the Leptos web framework."

[dependencies]
axum = { version = "0.6", default-features = false, features = [
	"matched-path",
] }
futures = "0.3"
http = "0.2.11"
hyper = "0.14.23"
# >>> Enabled ssr feature, but not tracing feature? <<<
leptos = { workspace = true, features = ["ssr"] }
leptos_meta = { workspace = true, features = ["ssr"] }
leptos_router = { workspace = true, features = ["ssr"] }
leptos_integration_utils = { workspace = true }
serde_json = "1"
tokio = { version = "1", default-features = false }
parking_lot = "0.12.1"
tokio-util = { version = "0.7.7", features = ["rt"] }
# >>> Hard dep on tracing, not behind feature flag <<<
tracing = "0.1.37"
once_cell = "1.17"
cfg-if = "1.0.0"

[features]
nonce = ["leptos/nonce"]
wasm = []
default = ["tokio/full", "axum/macros"]
experimental-islands = ["leptos_integration_utils/experimental-islands"]

@DanielJoyce
Copy link
Author

Hmm, still can't see how this is enabling the tracing feature on leptos itself?

@gbj
Copy link
Collaborator

gbj commented Jan 5, 2024

Thanks. It's specific to the #[component] macro somewhere.

MRE:

main.rs

use leptos::{component, IntoView};

#[component]
fn SignupForm() -> impl IntoView {}

Cargo.toml

[package]
name = "las"
version = "0.1.0"
edition = "2021"

[dependencies]
leptos = "0.5.4"
leptos_axum = "0.5.4"

cargo check. (Whatever is emitting ::tracing from the component macro is only doing it in debug mode, so cargo check --release is fine.)

@gbj
Copy link
Collaborator

gbj commented Jan 5, 2024

Oh okay yeah it's this:

#[cfg_attr(
any(debug_assertions, feature="ssr"),
::leptos::leptos_dom::tracing::instrument(level = "info", name = #trace_name, skip_all)
)]

Using the tracing::instrument macro requires a root-level tracing dependency that we can't tell to use some other path (like the one reexported from Leptos) instead.

Gating this on the Leptos tracing feature is a breaking change but we're releasing a 0.6 soon so it could be rolled into that.

(In the meantime tracing is a great crate, so either just adding it or running in release mode for a while should work.)

@gbj gbj added this to the 0.6 milestone Jan 5, 2024
@gbj gbj added bug Something isn't working and removed needs reproduction labels Jan 5, 2024
@DanielJoyce
Copy link
Author

Ahhh

in lib.rs ( but also in many other files)

#[proc_macro]
#[cfg_attr(
    any(debug_assertions, feature = "ssr"),
    tracing::instrument(level = "trace", skip_all,)
)]
pub fn view(tokens: TokenStream) -> TokenStream {

If ssr feature is enabled, which leptos-axum does, then a dependency on the tracing crate is brought in. ssr feature has a hidden dependency on tracing not expressed in the Cargo files.

while the error is shown as originating on the component macro, the actual issue is with the view!() macro. When this macro is expanded in my code, it injects a direct dependency on tracing in the scope of my code, not

Fix is to have ssr feature also turn on tracing, or rework the cfg_attribute. Have not tested. ymmv

#[cfg_attr(
    any(debug_assertions, all(feature = "ssr", feature = "tracing")), // If test build or ssr & tracing enabled
    tracing::instrument(level = "info", skip_all) // then instrument with tracing because we know 
)]
pub fn view(tokens: TokenStream) -> TokenStream {

Though perhaps all usages of cfg_attr referencing ssr should be fixed up?

@DanielJoyce
Copy link
Author

Here is the expanded main.rs

Note that the file now has dependencies on tracing.

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
use leptos::{component, view, IntoView};
/// Props for the [`SignupForm`] component.
///
///
#[builder(crate_module_path = ::leptos::typed_builder)]
struct SignupFormProps {}
#[automatically_derived]
impl SignupFormProps {
    /**
                Create a builder for building `SignupFormProps`.
                On the builder, call  to set the values of the fields.
                Finally, call `.build()` to create the instance of `SignupFormProps`.
                */
    #[allow(dead_code, clippy::default_trait_access)]
    fn builder() -> SignupFormPropsBuilder<()> {
        SignupFormPropsBuilder {
            fields: (),
            phantom: ::core::default::Default::default(),
        }
    }
}
#[must_use]
#[doc(hidden)]
#[allow(dead_code, non_camel_case_types, non_snake_case)]
struct SignupFormPropsBuilder<TypedBuilderFields = ()> {
    fields: TypedBuilderFields,
    phantom: ::core::marker::PhantomData<()>,
}
#[automatically_derived]
impl<TypedBuilderFields> Clone for SignupFormPropsBuilder<TypedBuilderFields>
where
    TypedBuilderFields: Clone,
{
    #[allow(clippy::default_trait_access)]
    fn clone(&self) -> Self {
        Self {
            fields: self.fields.clone(),
            phantom: ::core::default::Default::default(),
        }
    }
}
#[allow(dead_code, non_camel_case_types, missing_docs)]
#[automatically_derived]
impl SignupFormPropsBuilder<()> {
    #[allow(clippy::default_trait_access, clippy::used_underscore_binding)]
    pub fn build(self) -> SignupFormProps {
        let () = self.fields;
        #[allow(deprecated)] SignupFormProps {}.into()
    }
}
#[allow(missing_docs)]
impl ::leptos::Props for SignupFormProps {
    type Builder = SignupFormPropsBuilder;
    fn builder() -> Self::Builder {
        SignupFormProps::builder()
    }
}
impl ::leptos::DynAttrs for SignupFormProps {
    fn dyn_attrs(mut self, v: Vec<(&'static str, ::leptos::Attribute)>) -> Self {
        self
    }
}
impl ::leptos::IntoView for SignupFormProps {
    fn into_view(self) -> ::leptos::View {
        SignupForm().into_view()
    }
}
///
#[allow(non_snake_case, clippy::too_many_arguments)]
#[allow(clippy::needless_lifetimes)]
#[allow(clippy::let_with_type_underscore)]
fn SignupForm() -> impl IntoView {
    {}
    #[allow(clippy::suspicious_else_formatting)]
    {
        let __tracing_attr_span;
        let __tracing_attr_guard;
        if tracing::Level::INFO <= ::tracing::level_filters::STATIC_MAX_LEVEL
            && tracing::Level::INFO <= ::tracing::level_filters::LevelFilter::current()
            || { false }
        {
            __tracing_attr_span = {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite = {
                    static META: ::tracing::Metadata<'static> = {
                        ::tracing_core::metadata::Metadata::new(
                            "<SignupForm />",
                            "leptos_bug",
                            tracing::Level::INFO,
                            ::core::option::Option::Some("src/main.rs"),
                            ::core::option::Option::Some(3u32),
                            ::core::option::Option::Some("leptos_bug"),
                            ::tracing_core::field::FieldSet::new(
                                &[],
                                ::tracing_core::callsite::Identifier(&__CALLSITE),
                            ),
                            ::tracing::metadata::Kind::SPAN,
                        )
                    };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
                let mut interest = ::tracing::subscriber::Interest::never();
                if tracing::Level::INFO <= ::tracing::level_filters::STATIC_MAX_LEVEL
                    && tracing::Level::INFO
                        <= ::tracing::level_filters::LevelFilter::current()
                    && {
                        interest = __CALLSITE.interest();
                        !interest.is_never()
                    }
                    && ::tracing::__macro_support::__is_enabled(
                        __CALLSITE.metadata(),
                        interest,
                    )
                {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta, &{ meta.fields().value_set(&[]) })
                } else {
                    let span = ::tracing::__macro_support::__disabled_span(
                        __CALLSITE.metadata(),
                    );
                    {};
                    span
                }
            };
            __tracing_attr_guard = __tracing_attr_span.enter();
        }
        #[warn(clippy::suspicious_else_formatting)]
        {
            #[allow(
                unknown_lints,
                unreachable_code,
                clippy::diverging_sub_expression,
                clippy::let_unit_value,
                clippy::unreachable,
                clippy::let_with_type_underscore,
                clippy::empty_loop
            )]
            if false {
                let __tracing_attr_fake_return: _ = loop {};
                return __tracing_attr_fake_return;
            }
            {
                let span = ::leptos::leptos_dom::tracing::Span::current();
                ::leptos::leptos_dom::Component::new(
                    "SignupForm",
                    move || {
                        #[cfg(debug_assertions)]
                        let _guard = span.entered();
                        __SignupForm()
                    },
                )
            }
        }
    }
}
#[doc(hidden)]
#[allow(non_snake_case, dead_code, clippy::too_many_arguments)]
fn __SignupForm() -> impl IntoView {
    {
        #[allow(unused_braces)]
        {
            let _ = ::leptos::leptos_dom::html::div;
            let _ = ::leptos::leptos_dom::html::div;
            let _ = ::leptos::leptos_dom::html::h1;
            let _ = ::leptos::leptos_dom::html::h1;
            ::leptos::HtmlElement::from_chunks(
                ::leptos::leptos_dom::html::Div::default(),
                [
                    leptos::leptos_dom::html::StringOrView::String(
                        {
                            let res = ::alloc::fmt::format(
                                format_args!(
                                    "<div{0}><h1{1}>Hello World</h1></div>",
                                    ::leptos::leptos_dom::HydrationCtx::peek().map(| id | { let
                                    res = ::alloc::fmt::format(format_args!(" data-hk=\"{0}\"",
                                    id)); res }).unwrap_or_default(),
                                    ::leptos::leptos_dom::HydrationCtx::id().map(| id | { let
                                    res = ::alloc::fmt::format(format_args!(" data-hk=\"{0}\"",
                                    id)); res }).unwrap_or_default()
                                ),
                            );
                            res
                        }
                            .into(),
                    ),
                ],
            )
        }
    }
}
fn main() {
    {
        ::std::io::_print(format_args!("Hello, world!\n"));
    };
}

@DanielJoyce
Copy link
Author

Yeah, I plan on using tracing anyways, but it was weird that adding leptos_axum was breaking for me.

@DanielJoyce
Copy link
Author

Sorry didn't see your updates in the midst of my analysis. Anyways more info is always better. :D

@gbj
Copy link
Collaborator

gbj commented Jan 5, 2024

Note that none of the cfg_attr instances you cite above cause an issue, because tracing is already a dependency of leptos, so it's available. It's specifically the fact that the tracing::instrument macro emits ::tracing, which means you need to have it in your Cargo.toml.

I'm honestly not sure why adding leptos_axum or not triggers the issue.

A PR would be welcome to fix this, although as I said I probably can't merge it until 0.6 (in the next few weeks).

@DanielJoyce
Copy link
Author

DanielJoyce commented Jan 5, 2024

Leptos_axum enables ssr feature on leptos, ssr via cfg-attr on view macro emits tracing calls when view!() macro is used.

So yes, its the cfg_attr emitting tracing attribute macros on the view macro when ssr is enabled.

@DanielJoyce
Copy link
Author

DanielJoyce commented Jan 5, 2024

leptos_auxm enables ssr on leptos

leptos ssr feature enables ssr on leptos_macro

leptos_macro, lib.rs:

#[proc_macro]
#[cfg_attr(
    any(debug_assertions, feature = "ssr"), // If Testing, or ssr feature enabled, then emit tracing 
    tracing::instrument(level = "trace", skip_all,)
)]
pub fn view(tokens: TokenStream) -> TokenStream {

@NfNitLoop
Copy link
Contributor

FWIW, I'm running into this issue as well. Yep, it's enabling ssr or debug_assertions that causes the issue. I'm seeing it without leptos axum (I'm currently using actix.)

Glad to see it's already triaged for 0.6! ❤️ And thanks for including the workaround!

@NfNitLoop
Copy link
Contributor

Just wanted to add, this was all working fine for me when I had my #[component]s defined in my top-level lib.rs. It only cropped up when I refactored them into a crate::views::foo module.

Might the fix be as simple as changing the import to ::tracing so that it's always treated as an extern?

@gbj
Copy link
Collaborator

gbj commented Jan 20, 2024

I was wrong about this one: what I noted was already gated on the tracing feature on leptos, but that was being enabled accidentally by leptos_meta, which is imported by leptos_axum.

I believe #2211 fixes this (or at least it does in the repro above).

@gbj gbj closed this as completed Jan 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants