diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2024-08-20 18:44:29 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2024-11-07 20:18:00 +0000 |
| commit | 8a568d9f15453cbfe5d6f45fa5f5bb32e58b93ed (patch) | |
| tree | 6495d08ac40944bab3a35295046dc1a57f732635 | |
| parent | 6fbf4441a33f64d546d501656c31d9c6985f1726 (diff) | |
| download | rust-8a568d9f15453cbfe5d6f45fa5f5bb32e58b93ed.tar.gz rust-8a568d9f15453cbfe5d6f45fa5f5bb32e58b93ed.zip | |
Remove less relevant info from diagnostic
```
error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied because the trait comes from a different crate version
--> multiple-dep-versions.rs:7:18
|
7 | do_something(Type);
| ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type`
|
note: there are multiple different versions of crate `dependency` in the dependency graph
--> /home/gh-estebank/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-1.rs:4:1
|
3 | pub struct Type(pub i32);
| --------------- this type implements the required trait
4 | pub trait Trait {
| ^^^^^^^^^^^^^^^ this is the required trait
|
::: multiple-dep-versions.rs:1:1
|
1 | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
2 | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
|
::: /home/gh-estebank/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-2.rs:3:1
|
3 | pub struct Type;
| --------------- this type doesn't implement the required trait
4 | pub trait Trait {
| --------------- this is the found trait
= note: two types coming from two different versions of the same crate are different types even if they look the same
= help: you can use `cargo tree` to explore your dependency tree
```
The approach to accomplish this is a HACK, and we'd want a better way to do this. I believe that moving E0277 to be a structured diagnostic would help in that regard.
| -rw-r--r-- | compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs | 18 | ||||
| -rw-r--r-- | tests/run-make/crate-loading/rmake.rs | 46 |
2 files changed, 38 insertions, 26 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 088fa668914..cb074261cde 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1796,6 +1796,24 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { StringPart::highlighted("cargo tree".to_string()), StringPart::normal("` to explore your dependency tree".to_string()), ]); + + // FIXME: this is a giant hack for the benefit of this specific diagnostic. Because + // we're so nested in method calls before the error gets emitted, bubbling a single bit + // flag informing the top level caller to stop adding extra detail to the diagnostic, + // would actually be harder to follow. So we do something naughty here: we consume the + // diagnostic, emit it and leave in its place a "delayed bug" that will continue being + // modified but won't actually be printed to end users. This *is not ideal*, but allows + // us to reduce the verbosity of an error that is already quite verbose and increase its + // specificity. Below we modify the main message as well, in a way that *could* break if + // the implementation of Diagnostics change significantly, but that would be caught with + // a make test failure when this diagnostic is tested. + err.primary_message(format!( + "{} because the trait comes from a different crate version", + err.messages[0].0.as_str().unwrap(), + )); + let diag = err.clone(); + err.downgrade_to_delayed_bug(); + self.tcx.dcx().emit_diagnostic(diag); return true; } diff --git a/tests/run-make/crate-loading/rmake.rs b/tests/run-make/crate-loading/rmake.rs index 544bf9ab957..2d5913c4bcb 100644 --- a/tests/run-make/crate-loading/rmake.rs +++ b/tests/run-make/crate-loading/rmake.rs @@ -18,37 +18,31 @@ fn main() { .extern_("dependency", rust_lib_name("dependency")) .extern_("dep_2_reexport", rust_lib_name("foo")) .run_fail() - .assert_stderr_contains(r#"error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied - --> multiple-dep-versions.rs:7:18 - | -7 | do_something(Type); - | ------------ ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type` - | | - | required by a bound introduced by this call - | + .assert_stderr_contains(r#"error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied because the trait comes from a different crate version + --> multiple-dep-versions.rs:7:18 + | +7 | do_something(Type); + | ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type` + | note: there are multiple different versions of crate `dependency` in the dependency graph"#) .assert_stderr_contains(r#" -3 | pub struct Type(pub i32); - | --------------- this type implements the required trait -4 | pub trait Trait { - | ^^^^^^^^^^^^^^^ this is the required trait +3 | pub struct Type(pub i32); + | --------------- this type implements the required trait +4 | pub trait Trait { + | ^^^^^^^^^^^^^^^ this is the required trait "#) .assert_stderr_contains(r#" -1 | extern crate dep_2_reexport; - | ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo` -2 | extern crate dependency; - | ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate"#) +1 | extern crate dep_2_reexport; + | ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo` +2 | extern crate dependency; + | ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate"#) .assert_stderr_contains(r#" -3 | pub struct Type; - | --------------- this type doesn't implement the required trait -4 | pub trait Trait { - | --------------- this is the found trait - = note: two types coming from two different versions of the same crate are different types even if they look the same - = help: you can use `cargo tree` to explore your dependency tree"#) - .assert_stderr_contains(r#"note: required by a bound in `do_something`"#) - .assert_stderr_contains(r#" -12 | pub fn do_something<X: Trait>(_: X) {} - | ^^^^^ required by this bound in `do_something`"#) +3 | pub struct Type; + | --------------- this type doesn't implement the required trait +4 | pub trait Trait { + | --------------- this is the found trait + = note: two types coming from two different versions of the same crate are different types even if they look the same + = help: you can use `cargo tree` to explore your dependency tree"#) .assert_stderr_contains(r#"error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope --> multiple-dep-versions.rs:8:10 | |
