Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more info on type/trait mismatches for different crate versions #133767

Merged
merged 1 commit into from
Dec 8, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 116 additions & 18 deletions compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
Original file line number Diff line number Diff line change
@@ -52,7 +52,9 @@ use std::{cmp, fmt, iter};

use rustc_abi::ExternAbi;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_errors::{Applicability, Diag, DiagStyledString, IntoDiagArg, StringPart, pluralize};
use rustc_errors::{
Applicability, Diag, DiagStyledString, IntoDiagArg, MultiSpan, StringPart, pluralize,
};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
@@ -67,6 +69,7 @@ use rustc_middle::ty::{
self, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt,
};
use rustc_span::def_id::LOCAL_CRATE;
use rustc_span::{BytePos, DesugaringKind, Pos, Span, sym};
use tracing::{debug, instrument};

@@ -211,7 +214,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}

/// Adds a note if the types come from similarly named crates
fn check_and_note_conflicting_crates(&self, err: &mut Diag<'_>, terr: TypeError<'tcx>) {
fn check_and_note_conflicting_crates(&self, err: &mut Diag<'_>, terr: TypeError<'tcx>) -> bool {
// FIXME(estebank): unify with `report_similar_impl_candidates`. The message is similar,
// even if the logic needed to detect the case is very different.
use hir::def_id::CrateNum;
use rustc_hir::definitions::DisambiguatedDefPathData;
use ty::GenericArg;
@@ -285,7 +290,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
}

let report_path_match = |err: &mut Diag<'_>, did1: DefId, did2: DefId| {
let report_path_match = |err: &mut Diag<'_>, did1: DefId, did2: DefId, ty: &str| -> bool {
// Only report definitions from different crates. If both definitions
// are from a local module we could have false positives, e.g.
// let _ = [{struct Foo; Foo}, {struct Foo; Foo}];
@@ -297,24 +302,112 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {

// We compare strings because DefPath can be different
// for imported and non-imported crates
let expected_str = self.tcx.def_path_str(did1);
let found_str = self.tcx.def_path_str(did2);
let Ok(expected_abs) = abs_path(did1) else { return false };
let Ok(found_abs) = abs_path(did2) else { return false };
let same_path = || -> Result<_, PrintError> {
Ok(self.tcx.def_path_str(did1) == self.tcx.def_path_str(did2)
|| abs_path(did1)? == abs_path(did2)?)
Ok(expected_str == found_str || expected_abs == found_abs)
};
// We want to use as unique a type path as possible. If both types are "locally
// known" by the same name, we use the "absolute path" which uses the original
// crate name instead.
let (expected, found) = if expected_str == found_str {
(expected_abs.join("::"), found_abs.join("::"))
} else {
(expected_str.clone(), found_str.clone())
};
if same_path().unwrap_or(false) {
let crate_name = self.tcx.crate_name(did1.krate);
let msg = if did1.is_local() || did2.is_local() {
// We've displayed "expected `a::b`, found `a::b`". We add context to
// differentiate the different cases where that might happen.
let expected_crate_name = self.tcx.crate_name(did1.krate);
let found_crate_name = self.tcx.crate_name(did2.krate);
let same_crate = expected_crate_name == found_crate_name;
let expected_sp = self.tcx.def_span(did1);
let found_sp = self.tcx.def_span(did2);

let both_direct_dependencies = if !did1.is_local()
&& !did2.is_local()
&& let Some(data1) = self.tcx.extern_crate(did1.krate)
&& let Some(data2) = self.tcx.extern_crate(did2.krate)
&& data1.dependency_of == LOCAL_CRATE
&& data2.dependency_of == LOCAL_CRATE
{
// If both crates are directly depended on, we don't want to mention that
// in the final message, as it is redundant wording.
// We skip the case of semver trick, where one version of the local crate
// depends on another version of itself by checking that both crates at play
// are not the current one.
true
} else {
false
};

let mut span: MultiSpan = vec![expected_sp, found_sp].into();
span.push_span_label(
self.tcx.def_span(did1),
format!("this is the expected {ty} `{expected}`"),
);
span.push_span_label(
self.tcx.def_span(did2),
format!("this is the found {ty} `{found}`"),
);
for def_id in [did1, did2] {
let crate_name = self.tcx.crate_name(def_id.krate);
if !def_id.is_local()
&& let Some(data) = self.tcx.extern_crate(def_id.krate)
{
let descr = if same_crate {
"one version of".to_string()
} else {
format!("one {ty} comes from")
};
let dependency = if both_direct_dependencies {
if let rustc_session::cstore::ExternCrateSource::Extern(def_id) =
data.src
&& let Some(name) = self.tcx.opt_item_name(def_id)
{
format!(", which is renamed locally to `{name}`")
} else {
String::new()
}
} else if data.dependency_of == LOCAL_CRATE {
", as a direct dependency of the current crate".to_string()
} else {
let dep = self.tcx.crate_name(data.dependency_of);
format!(", as a dependency of crate `{dep}`")
};
span.push_span_label(
data.span,
format!("{descr} crate `{crate_name}` used here{dependency}"),
);
}
}
let msg = if (did1.is_local() || did2.is_local()) && same_crate {
format!(
"the crate `{expected_crate_name}` is compiled multiple times, \
possibly with different configurations",
)
} else if same_crate {
format!(
"the crate `{crate_name}` is compiled multiple times, possibly with different configurations"
"two different versions of crate `{expected_crate_name}` are being \
used; two types coming from two different versions of the same crate \
are different types even if they look the same",
)
} else {
format!(
"perhaps two different versions of crate `{crate_name}` are being used?"
"two types coming from two different crates are different types even \
if they look the same",
)
};
err.note(msg);
err.span_note(span, msg);
if same_crate {
err.help("you can use `cargo tree` to explore your dependency tree");
}
return true;
}
}
false
};
match terr {
TypeError::Sorts(ref exp_found) => {
@@ -323,14 +416,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
if let (&ty::Adt(exp_adt, _), &ty::Adt(found_adt, _)) =
(exp_found.expected.kind(), exp_found.found.kind())
{
report_path_match(err, exp_adt.did(), found_adt.did());
return report_path_match(err, exp_adt.did(), found_adt.did(), "type");
}
}
TypeError::Traits(ref exp_found) => {
report_path_match(err, exp_found.expected, exp_found.found);
return report_path_match(err, exp_found.expected, exp_found.found, "trait");
}
_ => (), // FIXME(#22750) handle traits and stuff
}
false
}

fn note_error_origin(
@@ -1409,6 +1503,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
label_or_note(span, terr.to_string(self.tcx));
}

if self.check_and_note_conflicting_crates(diag, terr) {
return;
}

if let Some((expected, found, path)) = expected_found {
let (expected_label, found_label, exp_found) = match exp_found {
Mismatch::Variable(ef) => (
@@ -1470,15 +1568,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|prim: Ty<'tcx>, shadow: Ty<'tcx>, defid: DefId, diag: &mut Diag<'_>| {
let name = shadow.sort_string(self.tcx);
diag.note(format!(
"{prim} and {name} have similar names, but are actually distinct types"
"`{prim}` and {name} have similar names, but are actually distinct types"
));
diag.note(format!(
"one `{prim}` is a primitive defined by the language",
));
diag.note(format!("{prim} is a primitive defined by the language"));
let def_span = self.tcx.def_span(defid);
let msg = if defid.is_local() {
format!("{name} is defined in the current crate")
format!("the other {name} is defined in the current crate")
} else {
let crate_name = self.tcx.crate_name(defid.krate);
format!("{name} is defined in crate `{crate_name}`")
format!("the other {name} is defined in crate `{crate_name}`")
};
diag.span_note(def_span, msg);
};
@@ -1666,8 +1766,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
}

self.check_and_note_conflicting_crates(diag, terr);

self.note_and_explain_type_err(diag, terr, cause, span, cause.body_id.to_def_id());
if let Some(exp_found) = exp_found
&& let exp_found = TypeError::Sorts(exp_found)
Original file line number Diff line number Diff line change
@@ -1745,9 +1745,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
};
(
data.span,
format!(
"one version of crate `{crate_name}` is used here, as a {dependency}"
),
format!("one version of crate `{crate_name}` used here, as a {dependency}"),
)
})
{
16 changes: 8 additions & 8 deletions tests/incremental/circular-dependencies.rs
Original file line number Diff line number Diff line change
@@ -6,10 +6,12 @@
//@ [cfail2] compile-flags: --test --extern aux={{build-base}}/circular-dependencies/auxiliary/libcircular_dependencies_aux.rmeta -L dependency={{build-base}}/circular-dependencies

pub struct Foo;
//[cfail2]~^ NOTE `Foo` is defined in the current crate
//[cfail2]~| NOTE `Foo` is defined in the current crate
//[cfail2]~| NOTE `circular_dependencies::Foo` is defined in crate `circular_dependencies`
//[cfail2]~| NOTE `circular_dependencies::Foo` is defined in crate `circular_dependencies`
//[cfail2]~^ NOTE the crate `circular_dependencies` is compiled multiple times, possibly with different configurations
//[cfail2]~| NOTE the crate `circular_dependencies` is compiled multiple times, possibly with different configurations
//[cfail2]~| NOTE this is the expected type `Foo`
//[cfail2]~| NOTE this is the expected type `circular_dependencies::Foo`
//[cfail2]~| NOTE this is the found type `Foo`
//[cfail2]~| NOTE this is the found type `circular_dependencies::Foo`

pub fn consume_foo(_: Foo) {}
//[cfail2]~^ NOTE function defined here
@@ -24,14 +26,12 @@ fn test() {
//[cfail2]~^ ERROR mismatched types [E0308]
//[cfail2]~| NOTE expected `circular_dependencies::Foo`, found `Foo`
//[cfail2]~| NOTE arguments to this function are incorrect
//[cfail2]~| NOTE `Foo` and `circular_dependencies::Foo` have similar names, but are actually distinct types
//[cfail2]~| NOTE the crate `circular_dependencies` is compiled multiple times, possibly with different configurations
//[cfail2]~| NOTE function defined here
//[cfail2]~| NOTE one version of crate `circular_dependencies` used here, as a dependency of crate `circular_dependencies_aux`
//[cfail2]~| NOTE one version of crate `circular_dependencies` used here, as a dependency of crate `circular_dependencies_aux`

consume_foo(aux::produce_foo());
//[cfail2]~^ ERROR mismatched types [E0308]
//[cfail2]~| NOTE expected `Foo`, found `circular_dependencies::Foo`
//[cfail2]~| NOTE arguments to this function are incorrect
//[cfail2]~| NOTE `circular_dependencies::Foo` and `Foo` have similar names, but are actually distinct types
//[cfail2]~| NOTE the crate `circular_dependencies` is compiled multiple times, possibly with different configurations
}
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ note: there are multiple different versions of crate `foo` in the dependency gra
--> foo-current.rs:7:1
|
4 | extern crate foo;
| ----------------- one version of crate `foo` is used here, as a direct dependency of the current crate
| ----------------- one version of crate `foo` used here, as a direct dependency of the current crate
5 |
6 | pub struct Struct;
| ----------------- this type implements the required trait
3 changes: 3 additions & 0 deletions tests/run-make/crate-loading/multiple-dep-versions-1.rs
Original file line number Diff line number Diff line change
@@ -5,8 +5,11 @@ pub trait Trait {
fn foo(&self);
fn bar();
}
pub trait Trait2 {}
impl Trait for Type {
fn foo(&self) {}
fn bar() {}
}
pub fn do_something<X: Trait>(_: X) {}
pub fn do_something_type(_: Type) {}
pub fn do_something_trait(_: Box<dyn Trait2>) {}
4 changes: 4 additions & 0 deletions tests/run-make/crate-loading/multiple-dep-versions-2.rs
Original file line number Diff line number Diff line change
@@ -5,8 +5,12 @@ pub trait Trait {
fn foo(&self);
fn bar();
}
pub trait Trait2 {}
impl Trait2 for Type {}
impl Trait for Type {
fn foo(&self) {}
fn bar() {}
}
pub fn do_something<X: Trait>(_: X) {}
pub fn do_something_type(_: Type) {}
pub fn do_something_trait(_: Box<dyn Trait2>) {}
2 changes: 1 addition & 1 deletion tests/run-make/crate-loading/multiple-dep-versions-3.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
#![crate_type = "rlib"]

extern crate dependency;
pub use dependency::Type;
pub use dependency::{Trait2, Type, do_something_trait, do_something_type};
pub struct OtherType;
impl dependency::Trait for OtherType {
fn foo(&self) {}
6 changes: 4 additions & 2 deletions tests/run-make/crate-loading/multiple-dep-versions.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
extern crate dep_2_reexport;
extern crate dependency;
use dep_2_reexport::{OtherType, Type};
use dependency::{Trait, do_something};
use dep_2_reexport::{OtherType, Trait2, Type};
use dependency::{Trait, do_something, do_something_trait, do_something_type};

fn main() {
do_something(Type);
Type.foo();
Type::bar();
do_something(OtherType);
do_something_type(Type);
do_something_trait(Box::new(Type) as Box<dyn Trait2>);
}
80 changes: 72 additions & 8 deletions tests/run-make/crate-loading/multiple-dep-versions.stderr
Original file line number Diff line number Diff line change
@@ -17,9 +17,9 @@ LL | pub trait Trait {
::: replaced
|
LL | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
| ---------------------------- one version of crate `dependency` used here, as a dependency of crate `foo`
LL | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
| ------------------------ one version of crate `dependency` used here, as a direct dependency of the current crate
|
::: replaced
|
@@ -51,7 +51,7 @@ LL | fn foo(&self);
|
::: replaced
|
LL | use dependency::{Trait, do_something};
LL | use dependency::{Trait, do_something, do_something_trait, do_something_type};
| ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`
|
::: replaced
@@ -76,7 +76,7 @@ LL | fn bar();
|
::: replaced
|
LL | use dependency::{Trait, do_something};
LL | use dependency::{Trait, do_something, do_something_trait, do_something_type};
| ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`
|
::: replaced
@@ -101,9 +101,9 @@ LL | pub trait Trait {
::: replaced
|
LL | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
| ---------------------------- one version of crate `dependency` used here, as a dependency of crate `foo`
LL | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
| ------------------------ one version of crate `dependency` used here, as a direct dependency of the current crate
|
::: replaced
|
@@ -121,7 +121,71 @@ note: required by a bound in `do_something`
LL | pub fn do_something<X: Trait>(_: X) {}
| ^^^^^ required by this bound in `do_something`

error: aborting due to 4 previous errors
error[E0308]: mismatched types
--> replaced
|
LL | do_something_type(Type);
| ----------------- ^^^^ expected `dependency::Type`, found `dep_2_reexport::Type`
| |
| arguments to this function are incorrect
|
note: two different versions of crate `dependency` are being used; two types coming from two different versions of the same crate are different types even if they look the same
--> replaced
|
LL | pub struct Type(pub i32);
| ^^^^^^^^^^^^^^^ this is the expected type `dependency::Type`
|
::: replaced
|
LL | pub struct Type;
| ^^^^^^^^^^^^^^^ this is the found type `dep_2_reexport::Type`
|
::: replaced
|
LL | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` used here, as a dependency of crate `foo`
LL | extern crate dependency;
| ------------------------ one version of crate `dependency` used here, as a direct dependency of the current crate
= help: you can use `cargo tree` to explore your dependency tree
note: function defined here
--> replaced
|
LL | pub fn do_something_type(_: Type) {}
| ^^^^^^^^^^^^^^^^^

error[E0308]: mismatched types
--> replaced
|
LL | do_something_trait(Box::new(Type) as Box<dyn Trait2>);
| ------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `dependency::Trait2`, found trait `dep_2_reexport::Trait2`
| |
| arguments to this function are incorrect
|
note: two different versions of crate `dependency` are being used; two types coming from two different versions of the same crate are different types even if they look the same
--> replaced
|
LL | pub trait Trait2 {}
| ^^^^^^^^^^^^^^^^ this is the expected trait `dependency::Trait2`
|
::: replaced
|
LL | pub trait Trait2 {}
| ^^^^^^^^^^^^^^^^ this is the found trait `dep_2_reexport::Trait2`
|
::: replaced
|
LL | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` used here, as a dependency of crate `foo`
LL | extern crate dependency;
| ------------------------ one version of crate `dependency` used here, as a direct dependency of the current crate
= help: you can use `cargo tree` to explore your dependency tree
note: function defined here
--> replaced
|
LL | pub fn do_something_trait(_: Box<dyn Trait2>) {}
| ^^^^^^^^^^^^^^^^^^

error: aborting due to 6 previous errors

Some errors have detailed explanations: E0277, E0599.
Some errors have detailed explanations: E0277, E0308, E0599.
For more information about an error, try `rustc --explain E0277`.
16 changes: 12 additions & 4 deletions tests/ui/mismatched_types/similar_paths_primitive.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
#![allow(non_camel_case_types)]

struct bool;
struct str;
struct bool; //~ NOTE the other `bool` is defined in the current crate
struct str; //~ NOTE the other `str` is defined in the current crate

fn foo(_: bool) {}
fn bar(_: &str) {}
fn foo(_: bool) {} //~ NOTE function defined here
fn bar(_: &str) {} //~ NOTE function defined here

fn main() {
foo(true);
//~^ ERROR mismatched types [E0308]
//~| NOTE expected `bool`, found a different `bool`
//~| NOTE arguments to this function are incorrect
//~| NOTE `bool` and `bool` have similar names, but are actually distinct types
//~| NOTE one `bool` is a primitive defined by the language
bar("hello");
//~^ ERROR mismatched types [E0308]
//~| NOTE expected `str`, found a different `str`
//~| NOTE arguments to this function are incorrect
//~| NOTE `str` and `str` have similar names, but are actually distinct types
//~| NOTE one `str` is a primitive defined by the language
}
14 changes: 7 additions & 7 deletions tests/ui/mismatched_types/similar_paths_primitive.stderr
Original file line number Diff line number Diff line change
@@ -6,9 +6,9 @@ LL | foo(true);
| |
| arguments to this function are incorrect
|
= note: bool and `bool` have similar names, but are actually distinct types
= note: bool is a primitive defined by the language
note: `bool` is defined in the current crate
= note: `bool` and `bool` have similar names, but are actually distinct types
= note: one `bool` is a primitive defined by the language
note: the other `bool` is defined in the current crate
--> $DIR/similar_paths_primitive.rs:3:1
|
LL | struct bool;
@@ -20,16 +20,16 @@ LL | fn foo(_: bool) {}
| ^^^ -------

error[E0308]: mismatched types
--> $DIR/similar_paths_primitive.rs:12:9
--> $DIR/similar_paths_primitive.rs:16:9
|
LL | bar("hello");
| --- ^^^^^^^ expected `str`, found a different `str`
| |
| arguments to this function are incorrect
|
= note: str and `str` have similar names, but are actually distinct types
= note: str is a primitive defined by the language
note: `str` is defined in the current crate
= note: `str` and `str` have similar names, but are actually distinct types
= note: one `str` is a primitive defined by the language
note: the other `str` is defined in the current crate
--> $DIR/similar_paths_primitive.rs:4:1
|
LL | struct str;
2 changes: 1 addition & 1 deletion tests/ui/type/auxiliary/crate_a1.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub struct Foo;

pub trait Bar{}
pub trait Bar {}

pub fn bar() -> Box<Bar> {
unimplemented!()
2 changes: 1 addition & 1 deletion tests/ui/type/auxiliary/crate_a2.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub struct Foo;

pub trait Bar{}
pub trait Bar {}

pub fn bar() -> Box<Bar> {
unimplemented!()
27 changes: 17 additions & 10 deletions tests/ui/type/type-mismatch-same-crate-name.rs
Original file line number Diff line number Diff line change
@@ -3,25 +3,32 @@

// This tests the extra note reported when a type error deals with
// seemingly identical types.
// The main use case of this error is when there are two crates
// (generally different versions of the same crate) with the same name
// causing a type mismatch. Here, we simulate that error using block-scoped
// aliased `extern crate` declarations.
// The main use case of this error is when there are two crates imported
// with the same name, causing a type mismatch. Here, we simulate that error
// using block-scoped aliased `extern crate` declarations.
// This is *not* the same case as two different crate versions in the
// dependency tree. That is tested in `tests/run-make/crate-loading/`.

fn main() {
let foo2 = {extern crate crate_a2 as a; a::Foo};
//~^ NOTE one type comes from crate `crate_a2` used here, which is renamed locally to `a`
//~| NOTE one trait comes from crate `crate_a2` used here, which is renamed locally to `a`
let bar2 = {extern crate crate_a2 as a; a::bar()};
{
extern crate crate_a1 as a;
//~^ NOTE one type comes from crate `crate_a1` used here, which is renamed locally to `a`
//~| NOTE one trait comes from crate `crate_a1` used here, which is renamed locally to `a`
a::try_foo(foo2);
//~^ ERROR mismatched types
//~| perhaps two different versions of crate `crate_a1`
//~| expected `main::a::Foo`, found a different `main::a::Foo`
//~| NOTE expected `main::a::Foo`, found a different `main::a::Foo`
//~| NOTE arguments to this function are incorrect
//~| NOTE two types coming from two different crates are different types even if they look the same
//~| NOTE function defined here
a::try_bar(bar2);
//~^ ERROR mismatched types
//~| perhaps two different versions of crate `crate_a1`
//~| expected trait `main::a::Bar`
//~| expected struct `Box<(dyn main::a::Bar + 'static)>`
//~| found struct `Box<dyn main::a::Bar>`
//~| NOTE expected trait `main::a::Bar`, found a different trait `main::a::Bar`
//~| NOTE arguments to this function are incorrect
//~| NOTE two types coming from two different crates are different types even if they look the same
//~| NOTE function defined here
}
}
45 changes: 33 additions & 12 deletions tests/ui/type/type-mismatch-same-crate-name.stderr
Original file line number Diff line number Diff line change
@@ -1,40 +1,61 @@
error[E0308]: mismatched types
--> $DIR/type-mismatch-same-crate-name.rs:16:20
--> $DIR/type-mismatch-same-crate-name.rs:21:20
|
LL | a::try_foo(foo2);
| ---------- ^^^^ expected `main::a::Foo`, found a different `main::a::Foo`
| |
| arguments to this function are incorrect
|
= note: `main::a::Foo` and `main::a::Foo` have similar names, but are actually distinct types
note: `main::a::Foo` is defined in crate `crate_a2`
note: two types coming from two different crates are different types even if they look the same
--> $DIR/auxiliary/crate_a2.rs:1:1
|
LL | pub struct Foo;
| ^^^^^^^^^^^^^^
note: `main::a::Foo` is defined in crate `crate_a1`
--> $DIR/auxiliary/crate_a1.rs:1:1
| ^^^^^^^^^^^^^^ this is the found type `crate_a2::Foo`
|
::: $DIR/auxiliary/crate_a1.rs:1:1
|
LL | pub struct Foo;
| ^^^^^^^^^^^^^^
= note: perhaps two different versions of crate `crate_a1` are being used?
| ^^^^^^^^^^^^^^ this is the expected type `crate_a1::Foo`
|
::: $DIR/type-mismatch-same-crate-name.rs:13:17
|
LL | let foo2 = {extern crate crate_a2 as a; a::Foo};
| --------------------------- one type comes from crate `crate_a2` used here, which is renamed locally to `a`
...
LL | extern crate crate_a1 as a;
| --------------------------- one type comes from crate `crate_a1` used here, which is renamed locally to `a`
note: function defined here
--> $DIR/auxiliary/crate_a1.rs:10:8
|
LL | pub fn try_foo(x: Foo){}
| ^^^^^^^

error[E0308]: mismatched types
--> $DIR/type-mismatch-same-crate-name.rs:20:20
--> $DIR/type-mismatch-same-crate-name.rs:27:20
|
LL | a::try_bar(bar2);
| ---------- ^^^^ expected trait `main::a::Bar`, found a different trait `main::a::Bar`
| |
| arguments to this function are incorrect
|
= note: expected struct `Box<(dyn main::a::Bar + 'static)>`
found struct `Box<dyn main::a::Bar>`
= note: perhaps two different versions of crate `crate_a1` are being used?
note: two types coming from two different crates are different types even if they look the same
--> $DIR/auxiliary/crate_a2.rs:3:1
|
LL | pub trait Bar {}
| ^^^^^^^^^^^^^ this is the found trait `crate_a2::Bar`
|
::: $DIR/auxiliary/crate_a1.rs:3:1
|
LL | pub trait Bar {}
| ^^^^^^^^^^^^^ this is the expected trait `crate_a1::Bar`
|
::: $DIR/type-mismatch-same-crate-name.rs:13:17
|
LL | let foo2 = {extern crate crate_a2 as a; a::Foo};
| --------------------------- one trait comes from crate `crate_a2` used here, which is renamed locally to `a`
...
LL | extern crate crate_a1 as a;
| --------------------------- one trait comes from crate `crate_a1` used here, which is renamed locally to `a`
note: function defined here
--> $DIR/auxiliary/crate_a1.rs:11:8
|
Loading