Skip to content

Commit 674a3d5

Browse files
committed
diagnostics: exclude indirect private deps from trait impl suggest
Fixes #88696
1 parent e36020c commit 674a3d5

File tree

4 files changed

+48
-1
lines changed

4 files changed

+48
-1
lines changed

Diff for: compiler/rustc_middle/src/ty/util.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
1515
use rustc_errors::ErrorGuaranteed;
1616
use rustc_hir as hir;
1717
use rustc_hir::def::{CtorOf, DefKind, Res};
18-
use rustc_hir::def_id::{DefId, LocalDefId};
18+
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
1919
use rustc_index::bit_set::GrowableBitSet;
2020
use rustc_index::{Idx, IndexVec};
2121
use rustc_macros::HashStable;
@@ -857,6 +857,27 @@ impl<'tcx> TyCtxt<'tcx> {
857857
_ => def_kind.article(),
858858
}
859859
}
860+
861+
/// Return `true` if the supplied `CrateNum` is "user-visible," meaning either a [public]
862+
/// dependency, or a [direct] private dependency. This is used to decide whether the crate can
863+
/// be shown in `impl` suggestions.
864+
///
865+
/// # Panics
866+
///
867+
/// This function assumes `key` exists.
868+
///
869+
/// [public]: TyCtxt::is_private_dep
870+
/// [direct]: rustc_session::cstore::ExternCrate::is_direct
871+
pub fn is_user_visible_dep(self, key: CrateNum) -> bool {
872+
// | Private | Direct | Visible | |
873+
// |---------|--------|---------|--------------------|
874+
// | Yes | Yes | Yes | !(true && !true) |
875+
// | No | Yes | Yes | !(false && !true) |
876+
// | Yes | No | No | !(true && !false) |
877+
// | No | No | Yes | !(false && !false) |
878+
!(self.is_private_dep(key)
879+
&& !self.extern_crate(key.as_def_id()).expect("crate must exist").is_direct())
880+
}
860881
}
861882

862883
struct OpaqueTypeExpander<'tcx> {

Diff for: compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
17751775
|| !trait_pred
17761776
.skip_binder()
17771777
.is_constness_satisfied_by(self.tcx.constness(def_id))
1778+
|| !self.tcx.is_user_visible_dep(def_id.krate)
17781779
{
17791780
return None;
17801781
}

Diff for: tests/ui/suggestions/issue-88696.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// This test case should ensure that miniz_oxide isn't
2+
// suggested, since it's not a direct dependency.
3+
4+
fn a() -> Result<u64, i32> {
5+
Err(1)
6+
}
7+
8+
fn b() -> Result<u32, i32> {
9+
a().into() //~ERROR [E0277]
10+
}
11+
12+
fn main() {
13+
let _ = dbg!(b());
14+
}

Diff for: tests/ui/suggestions/issue-88696.stderr

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0277]: the trait bound `Result<u32, i32>: From<Result<u64, i32>>` is not satisfied
2+
--> $DIR/issue-88696.rs:9:9
3+
|
4+
LL | a().into()
5+
| ^^^^ the trait `From<Result<u64, i32>>` is not implemented for `Result<u32, i32>`
6+
|
7+
= note: required for `Result<u64, i32>` to implement `Into<Result<u32, i32>>`
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)