To analyze a target project it must compile with the nightly version of rustc used by Paralegal (the one set here).

This can lead to dependencies of your project failing to build due to a missing rustc feature, even if the dependency does not use nightly rust. The reason is that the feature may have been stabilized since.

This was first encountered with the time crate version 0.3.20 in actix applications. And the error looks as follows. The solutions will reference this particular incident, but you may see the same error for different crates and the solutions should still apply.

Screen Shot 2023-04-05 at 3.51.51 PM.png

The best solution at the moment depends on your use case:

# in Paralegal.toml that is placed in the same directory
# as the Cargo.toml for the project you are trying to analyze.

[dep.time]
rust_features = ["explicit_generic_args_with_impl_trait"]

This solution is usually preferable, because it enables the feature only for that specific crate and is less involved than some other methods below.

Other solutions

  1. Passing a crate flag.

    You can enable the feature globally via RUSTFLAGS by setting RUSTFLAGS="-Zcrate-attr=feature(the_feature)_name".

    For instance setting it for a singe command RUSTFLAGS="-Zcrate=attr=feature(explicit_generic_args_with_impl_trait)" cargo paralegal-flow or globally for your shell session

    export RUSTFLAGS="-Zcrate=attr=feature(explicit_generic_args_with_impl_trait)"
    cargo paralegal-flow
    

    <aside> ⚠️ Caveat: Because this sets the feature for all crates it can also fail the build. In particular if the feature is a std library feature and one of the crates compiles with nostd, in which case an unavoidable error with “unknown feature” will be thrown.

    </aside>

  2. Pinning the dependency.

    You can pin time to a specific earlier version in the Cargo.toml like so

    time = "0.2.27"
    

    This can work, even if originally your top-level project did not directly depend on time but it was pulled in transitively.

  3. Use a Cargo.lock that works.

    You may have to build with --locked afterwards to prevent cargo from updating the dependencies in the lockfile. The one from ‣ is one you could use, but that is a project depending on rocket, not actix or axum.

  4. Override the dependency source with a fixed version

    You can get the source code for the version of time, then fix the errors by adding the actual feature annotations, for time this would be #![feature(explicit_generic_args_with_impl_trait)], to the lib.rs and then override the dependency specification in your Cargo.toml as below

    [replace]
    "time:0.3.20" = { path = "use/your/path/here" }
    

    This is a general dependency specification so you can also use a git repository instead of a path (you cannot use a version constraint though).

    Be aware that this overrides a specific version of time and if you run cargo update it may no longer use that version, necessitating an update of the replace. You can also use a patch section instead as shown below. I haven’t tried this but I fear this will set all time dependencies (regardless of version) to the one you’ve specified which may cause conflicts if some crates specifically depend on older time versions.

    [patch]
    time = { path = "use/your/path/here" }