diagnostics: exclude indirect private deps from trait impl suggest

Fixes #88696
This commit is contained in:
Michael Howell 2023-05-01 12:05:20 -07:00
parent e36020cdb3
commit 674a3d5c1c
4 changed files with 48 additions and 1 deletions

View File

@ -15,7 +15,7 @@
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;
@ -857,6 +857,27 @@ pub fn def_kind_descr_article(self, def_kind: DefKind, def_id: DefId) -> &'stati
_ => 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> {

View File

@ -1775,6 +1775,7 @@ fn find_similar_impl_candidates(
|| !trait_pred
.skip_binder()
.is_constness_satisfied_by(self.tcx.constness(def_id))
|| !self.tcx.is_user_visible_dep(def_id.krate)
{
return None;
}

View File

@ -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());
}

View File

@ -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`.