Skip to content

Commit 263e0c7

Browse files
committed
Untruthful multiple different versions of a crate in the dependency graph
Currently, If `expected_def_id` and `another_trait_def_id` have their crate imported as ExternCrateSource::Path the method get_extern_crate_renamed_symbol() will return None for both, resulting in a false positive. This fixes the issue by using a slitly different approach, we use a predicate instead and do the comparison of the item names only when both crates are imported as ExternCrateSource::Extern and are direct dependencies of the LOCAL_CRATE, otherwise false is returned.
1 parent d682af8 commit 263e0c7

File tree

5 files changed

+69
-14
lines changed

5 files changed

+69
-14
lines changed

compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::{fmt, iter};
1212
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
1313
use rustc_data_structures::unord::UnordSet;
1414
use rustc_errors::{Applicability, Diag, E0038, E0276, MultiSpan, struct_span_code_err};
15-
use rustc_hir::def_id::{DefId, LocalDefId};
15+
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
1616
use rustc_hir::intravisit::Visitor;
1717
use rustc_hir::{self as hir, AmbigArg};
1818
use rustc_infer::traits::solve::Goal;
@@ -22,7 +22,8 @@ use rustc_infer::traits::{
2222
};
2323
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
2424
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _};
25-
use rustc_span::{DesugaringKind, ErrorGuaranteed, ExpnKind, Span, Symbol};
25+
use rustc_session::cstore::{ExternCrate, ExternCrateSource};
26+
use rustc_span::{DesugaringKind, ErrorGuaranteed, ExpnKind, Span};
2627
use tracing::{info, instrument};
2728

2829
pub use self::overflow::*;
@@ -353,14 +354,33 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
353354
}
354355
}
355356

356-
fn get_extern_crate_renamed_symbol(&self, trait_def_id: DefId) -> Option<Symbol> {
357-
if !trait_def_id.is_local()
358-
&& let Some(data) = self.tcx.extern_crate(trait_def_id.krate)
359-
&& let rustc_session::cstore::ExternCrateSource::Extern(def_id) = data.src
360-
{
361-
self.tcx.opt_item_name(def_id)
362-
} else {
363-
None
357+
fn extern_crates_with_the_same_name(
358+
&self,
359+
expected_def_id: DefId,
360+
trait_def_id: DefId,
361+
) -> bool {
362+
if expected_def_id.is_local() || trait_def_id.is_local() {
363+
return false;
364+
}
365+
match (
366+
self.tcx.extern_crate(expected_def_id.krate),
367+
self.tcx.extern_crate(trait_def_id.krate),
368+
) {
369+
(
370+
Some(ExternCrate {
371+
src: ExternCrateSource::Extern(expected_def_id),
372+
dependency_of: krate1,
373+
..
374+
}),
375+
Some(ExternCrate {
376+
src: ExternCrateSource::Extern(trait_def_id),
377+
dependency_of: krate2,
378+
..
379+
}),
380+
) if (*krate1, *krate2) == (LOCAL_CRATE, LOCAL_CRATE) => {
381+
self.tcx.item_name(expected_def_id) == self.tcx.item_name(trait_def_id)
382+
}
383+
_ => false,
364384
}
365385
}
366386

@@ -377,13 +397,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
377397
{
378398
let krate = self.tcx.crate_name(expected_did.krate);
379399
let name = self.tcx.item_name(expected_did);
380-
let locally_renamed_krate = self
381-
.get_extern_crate_renamed_symbol(expected_did)
382-
.map_or(None, |s| if s != krate { Some(s) } else { None });
383400
let definitions_with_same_path: UnordSet<_> = found_dids
384401
.filter(|def_id| {
385402
def_id.krate != expected_did.krate
386-
&& (locally_renamed_krate == self.get_extern_crate_renamed_symbol(*def_id)
403+
&& (self.extern_crates_with_the_same_name(expected_did, *def_id)
387404
|| self.tcx.crate_name(def_id.krate) == krate)
388405
&& self.tcx.item_name(def_id) == name
389406
})
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//@ aux-crate:crate2=crate2.rs
2+
3+
pub trait Trait {}
4+
5+
pub fn foo(_arg: impl Trait) {}
6+
7+
pub fn bar(_arg: impl crate2::Trait) {}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub trait Trait {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// https://github.com/rust-lang/rust/issues/148892
2+
//@ aux-crate:crate1=crate1.rs
3+
4+
struct MyStruct; //~ HELP the trait `Trait` is not implemented for `MyStruct`
5+
6+
fn main() {
7+
crate1::foo(MyStruct); //~ ERROR the trait bound `MyStruct: Trait` is not satisfied
8+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0277]: the trait bound `MyStruct: Trait` is not satisfied
2+
--> $DIR/wrong-multiple-different-versions-of-a-crate.rs:7:17
3+
|
4+
LL | crate1::foo(MyStruct);
5+
| ----------- ^^^^^^^^ unsatisfied trait bound
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
help: the trait `Trait` is not implemented for `MyStruct`
10+
--> $DIR/wrong-multiple-different-versions-of-a-crate.rs:4:1
11+
|
12+
LL | struct MyStruct;
13+
| ^^^^^^^^^^^^^^^
14+
note: required by a bound in `foo`
15+
--> $DIR/auxiliary/crate1.rs:5:23
16+
|
17+
LL | pub fn foo(_arg: impl Trait) {}
18+
| ^^^^^ required by this bound in `foo`
19+
20+
error: aborting due to 1 previous error
21+
22+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)