Skip to content

Commit

Permalink
diagnostics: exclude indirect private deps from trait impl suggest
Browse files Browse the repository at this point in the history
  • Loading branch information
notriddle committed May 8, 2023
1 parent 28b7747 commit 7c673c6
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 1 deletion.
23 changes: 22 additions & 1 deletion compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
use rustc_index::bit_set::GrowableBitSet;
use rustc_index::{Idx, IndexVec};
use rustc_macros::HashStable;
Expand Down Expand Up @@ -808,6 +808,27 @@ impl<'tcx> TyCtxt<'tcx> {
_ => def_kind.article(),
}
}

/// Return `true` if the supplied `CrateNum` is "user-visible," meaning either a [public]
/// dependency, or a [direct] private dependency. This is used to decide whether the crate can
/// be shown in `impl` suggestions.
///
/// # Panics
///
/// This function assumes `key` exists.
///
/// [public]: TyCtxt::is_private_dep
/// [direct]: rustc_session::cstore::ExternCrate::is_direct
pub fn is_user_visible_dep(self, key: CrateNum) -> bool {
// | Private | Direct | Visible | |
// |---------|--------|---------|--------------------|
// | Yes | Yes | Yes | !(true && !true) |
// | No | Yes | Yes | !(false && !true) |
// | Yes | No | No | !(true && !false) |
// | No | No | Yes | !(false && !false) |
!(self.is_private_dep(key)
&& !self.extern_crate(key.as_def_id()).expect("crate must exist").is_direct())
}
}

struct OpaqueTypeExpander<'tcx> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1761,6 +1761,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|| !trait_pred
.skip_binder()
.is_constness_satisfied_by(self.tcx.constness(def_id))
|| !self.tcx.is_user_visible_dep(def_id.krate)
{
return None;
}
Expand Down
14 changes: 14 additions & 0 deletions tests/ui/suggestions/issue-88696.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// This test case should ensure that miniz_oxide isn't
// suggested, since it's not a direct dependency.

fn a() -> Result<u64, i32> {
Err(1)
}

fn b() -> Result<u32, i32> {
a().into() //~ERROR [E0277]
}

fn main() {
let _ = dbg!(b());
}
11 changes: 11 additions & 0 deletions tests/ui/suggestions/issue-88696.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0277]: the trait bound `Result<u32, i32>: From<Result<u64, i32>>` is not satisfied
--> $DIR/issue-88696.rs:9:9
|
LL | a().into()
| ^^^^ the trait `From<Result<u64, i32>>` is not implemented for `Result<u32, i32>`
|
= note: required for `Result<u64, i32>` to implement `Into<Result<u32, i32>>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.

0 comments on commit 7c673c6

Please sign in to comment.