簡體   English   中英

為什么 cargo build 不顯示具有不兼容依賴項的編譯錯誤?

[英]Why is cargo build not showing compilation errors with incompatible dependencies?

由於這個問題涉及多個依賴關系,我不確定從哪個方向尋找重現它,我希望可以根據具體示例詢問它。 這個問題背后更普遍的模式是:有一個依賴鏈user => libExtension => libBase並且libExtensionlibBase不兼容。

geo-booleanop項目中,我們遇到了一個我們無法完全理解的有趣問題 它涉及以下軟件包的相互作用:

  • geo-types ( libBase ) :一個核心庫,提供基本類型,如線條、矩形、多邊形等。
  • geo-booleanop ( libExtension ) : 一個建立在地理類型之上的庫,使用一個新功能對其進行擴展:一個新的特性BooleanOp ,具有交叉/聯合/...等功能,並針對地理類型中的多邊形類型實現.
  • 任何用戶 package 將 geo-types 和 geo-booleanop 結合在一起,旨在將BooleanOp特征用於多邊形。

package 地理類型最近從版本 0.4 到 0.5 發生了重大變化,例如,它將其Rect類型的一些字段從 pub 字段更改為 getter。

geo-booleanop package 尚未用於此更改,即,它仍然顯式使用這些 pub 字段。 目前,geo- Cargo.toml的 Cargo.toml 指定geo-types = "0.4" ,並且嘗試將其提高到 0.5 並在 geo-booleanop 中進行cargo build會導致在 pub 字段訪問時出現預期的編譯器錯誤。

現在令人驚訝的是:當創建一個結合了最新版本的地理類型和地理布爾運算的用戶 package 時,我們看到以下 output 來自用戶 ZEFE90A8E604A7C840E88D8B7D 中的cargo build

$ cargo build
[...]
   Compiling geo-booleanop v0.2.1
   Compiling geo-types v0.5.0
[...]

error[E0599]: no method named `union` found for type `geo_types::polygon::Polygon<{float}>` in the current scope
  --> src/main.rs:21:23
   |
21 |     let union = poly1.union(&poly2);
   |                       ^^^^^ method not found in `geo_types::polygon::Polygon<{float}>`

這令人驚訝,因為:

  • 根本不可能將 geo-booleanop v0.2.1 與地理類型 v0.5.0 結合起來編譯,因為它們不兼容。
  • 關於沒有名為union的方法的錯誤令人困惑,因為用戶代碼正確地將BooleanOp特征帶入 scope,它應該為多邊形提供准確的方法。
  • 具有諷刺意味的是,編譯器還輸出未使用BooleanOp特征導入的警告。

我的問題是:

  • 為什么cargo build沒有顯示突出依賴項不兼容的編譯錯誤?
  • 如果這是設計使然,我們可以在 geo-booleanop 網站上做些什么來讓我們的用戶更容易掌握這些問題嗎? 目前,他們在編寫代碼方面做的一切都是正確的,以將特征帶入 scope,但編譯器的行為就好像特征缺失一樣——而實際上它是版本不匹配。 我們可以在圖書館網站上強制執行更明確的錯誤嗎?

詳細信息以防萬一:

  • BooleanOp特征在其底層浮點類型中是通用的( 參見實現)。 這是否會導致問題,因為 generics 在客戶端代碼像在其他編程語言中一樣使用它之前不會被實例化?
  • 這是復制的客戶端代碼: main.rsCargo.toml

我將您的情況總結如下:

  • 您的 Cargo.toml 取決於geo-booleanop 0.2.1 和geo-types 0.5.0
  • geo-booleanop 0.2.1 取決於geo-types 0.4.x

如果查看 Cargo.lock 文件,您會注意到geo-types有兩個[[package]]條目,一個用於0.4.x ,一個用於0.5.0

當同一個項目的兩個(傳遞)依賴需求不兼容時,cargo 實際上會嘗試編譯它們 Cargo 不會將間接依賴項暴露給您的 crate,因此 Cargo 會分別構建兩個版本,就好像它們沒有相同的 crate 名稱一樣。 只要您不嘗試將geo-typesgeo-booleanop使用,它們實際上就可以獨立工作。

為清楚起見,我分別稱這兩個版本geo_types_04geo_types_05 geo-booleanop 適用於名為geo_types_04的依賴項,其中geo_types_04不會暴露給您的 crate,因此您根本不需要關心geo_types_04是否被使用。

只有當geo-booleanop公開接受/返回 geo_types_04 中定義的某些類型的geo_types_04時,它才會成為問題。 然后你假設它是geo_types_05 ,導致不兼容。

這次你的錯誤實際上是更易讀的錯誤之一。有時你會得到像Expected geo_types::Line, got geo_types::Line這樣的錯誤,因為 function 接受geo_types_04::Line是用geo_types_05::Line Line 調用的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM