Rust 为什么锈宏从另一个板条箱重新导出工作,除非存在';这是一种依赖冲突

Rust 为什么锈宏从另一个板条箱重新导出工作,除非存在';这是一种依赖冲突,rust,trace,rust-cargo,rust-tokio,Rust,Trace,Rust Cargo,Rust Tokio,我正在写一个生锈的板条箱供公司内部使用,它包装了出色的Tokio追踪板条箱,还有一些附加功能。我不仅在跟踪中重新导出宏,而且还添加了一些自己的宏,它们在内部调用跟踪宏。我的目标是使所有其他内部板条箱仅依赖于我的包装板条箱,而不必在每个板条箱中明确地拉入跟踪依赖项 这真的很有效,直到今天我遇到了一个问题,花了我几个小时来隔离。我已经做了一个简单的例子来说明这种行为 在本例中,我有一个带有两个板条箱的工作区:mylogger板条箱,它包装跟踪,并公开宏打印跟踪,以及一个二进制板条箱我的二进制板条箱,

我正在写一个生锈的板条箱供公司内部使用,它包装了出色的Tokio
追踪
板条箱,还有一些附加功能。我不仅在
跟踪
中重新导出宏,而且还添加了一些自己的宏,它们在内部调用
跟踪
宏。我的目标是使所有其他内部板条箱仅依赖于我的包装板条箱,而不必在每个板条箱中明确地拉入
跟踪
依赖项

这真的很有效,直到今天我遇到了一个问题,花了我几个小时来隔离。我已经做了一个简单的例子来说明这种行为

在本例中,我有一个带有两个板条箱的工作区:
mylogger板条箱
,它包装
跟踪
,并公开宏
打印跟踪,以及一个二进制板条箱
我的二进制板条箱
,它依赖于
我的记录器板条箱
,并调用
函数中的宏

我的记录器板条箱的
Cargo.toml
非常简单;我在自动生成的框架中添加的唯一内容是
跟踪
依赖项:

[package]
name = "my-logger-crate"
version = "0.1.0"
authors = ["Adam Nelson <anelson@users.noreply.github.com>"]
edition = "2018"

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

[dependencies]
tracing = "0.1.12"
这是由
我的二进制板条箱使用的,它的
货物。toml
也很简单:

[package]
name = "my-binary-crate"
version = "0.1.0"
authors = ["Adam Nelson <anelson@users.noreply.github.com>"]
edition = "2018"

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

[dependencies]
my-logger-crate = { path = "../my-logger-crate" }

# If the following line is uncommented, then the call to `print_trace!` in `main()` fails to compile.
# tower = "0.3"
如果
my binary crate
没有任何冲突的依赖项,则编译并运行良好

但是看看如果我们依赖文件中的
tower
,会发生什么:

打印跟踪宏正在扩展到
跟踪::跟踪宏,然后扩展到
跟踪::事件,然后扩展到代码以记录事件,其中包括调用
跟踪::…
。在我添加
tower
依赖项之前,所有这些都可以正常工作,因此很明显,编译器能够正确地解析
跟踪::…
,即使
我的二进制机箱
跟踪本身没有直接依赖关系

我怀疑这与依赖冲突有关
tower
拉入一个长的依赖关系树,包括
tower buffer
,它本身依赖于
tracing=“0.1.2”

我对Cargo如何解决这一看似冲突的理解是,它将使用
跟踪
版本
0.1.12
,因为我的日志箱明确依赖于
=0.1.12
,而
塔缓冲区
指定
0.1.2
,这相当于
^0.1.2
。但是我不明白为什么添加这个额外的依赖关系树会破坏宏的使用

目前,我已经通过在所有使用我的日志板条箱的下游板条箱中添加对
跟踪的显式依赖来解决这个问题,但这远远不够理想

我在启用宏跟踪的情况下运行:

$RUSTFLAGS=“-Z宏回溯”货物+夜间测试
编译我的二进制板条箱v0.1.0(/home/cornelius/scrap/e2780c4bd3dfa24758fcfd93e225b100/我的二进制板条箱)
错误[E0433]:未能解决:使用未声明的类型或模块跟踪`
--> :78:17
|
1 |/(@{$(,)*$($out:expr),*$(,)*},$fmt:expr,字段:$(,)*)=>
2 | |{format_args!($fmt,$($out),*)};
3 | |(@{$(,)*$($out:expr),*},$fmt:expr,字段:$($k:ident)+
4 | |=?$val:expr$(,)*)=>
...      |
78 | |(@{},跟踪::__mk_格式_字符串!($($kv)*),字段:$
||^^^^^^使用未声明的类型或模块`跟踪`
79 | |($kv)*)
80  |    |      }
81  |    |  } ;
... [大量宏观扩张被切断]
毫不奇怪,错误是试图调用
跟踪::_mk_format_string,失败原因是
我的二进制板条箱
没有引用此类板条箱
跟踪
。奇怪的是,为了得到这个错误,必须计算
跟踪中的其他几个宏。也许这是
跟踪中的一个bug,它应该是
$cratet::\uuuumk\uformat\ustring。然而,直到我在我的二进制板条箱上添加了一个
tower
依赖项,我仍然不明白为什么这样做有效

[package]
name = "my-binary-crate"
version = "0.1.0"
authors = ["Adam Nelson <anelson@users.noreply.github.com>"]
edition = "2018"

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

[dependencies]
my-logger-crate = { path = "../my-logger-crate" }

# If the following line is uncommented, then the call to `print_trace!` in `main()` fails to compile.
tower = "0.3"