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 note for mismatched types because of circular dependencies #105793

Merged
merged 2 commits into from
Mar 19, 2023
Merged
Show file tree
Hide file tree
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
21 changes: 14 additions & 7 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,9 +613,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}

let report_path_match = |err: &mut Diagnostic, did1: DefId, did2: DefId| {
// Only external crates, if either is from a local
// module we could have false positives
if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate {
// 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}];
if did1.krate != did2.krate {
let abs_path =
|def_id| AbsolutePathPrinter { tcx: self.tcx }.print_def_path(def_id, &[]);

Expand All @@ -627,10 +628,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
};
if same_path().unwrap_or(false) {
let crate_name = self.tcx.crate_name(did1.krate);
err.note(&format!(
"perhaps two different versions of crate `{}` are being used?",
crate_name
));
let msg = if did1.is_local() || did2.is_local() {
format!(
"the crate `{crate_name}` is compiled multiple times, possibly with different configurations"
)
} else {
format!(
"perhaps two different versions of crate `{crate_name}` are being used?"
)
};
err.note(msg);
}
}
};
Expand Down
50 changes: 35 additions & 15 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,13 +278,15 @@ impl<'test> TestCx<'test> {
Incremental => {
let revision =
self.revision.expect("incremental tests require a list of revisions");
if revision.starts_with("rpass") || revision.starts_with("rfail") {
if revision.starts_with("cpass")
|| revision.starts_with("rpass")
|| revision.starts_with("rfail")
{
true
} else if revision.starts_with("cfail") {
// FIXME: would be nice if incremental revs could start with "cpass"
pm.is_some()
} else {
panic!("revision name must begin with rpass, rfail, or cfail");
panic!("revision name must begin with cpass, rpass, rfail, or cfail");
}
}
mode => panic!("unimplemented for mode {:?}", mode),
Expand Down Expand Up @@ -384,6 +386,20 @@ impl<'test> TestCx<'test> {
}
}

fn run_cpass_test(&self) {
let emit_metadata = self.should_emit_metadata(self.pass_mode());
let proc_res = self.compile_test(WillExecute::No, emit_metadata);

if !proc_res.status.success() {
self.fatal_proc_rec("compilation failed!", &proc_res);
}

// FIXME(#41968): Move this check to tidy?
if !errors::load_errors(&self.testpaths.file, self.revision).is_empty() {
self.fatal("compile-pass tests with expected warnings should be moved to ui/");
}
}

fn run_rpass_test(&self) {
let emit_metadata = self.should_emit_metadata(self.pass_mode());
let should_run = self.run_if_enabled();
Expand All @@ -393,17 +409,15 @@ impl<'test> TestCx<'test> {
self.fatal_proc_rec("compilation failed!", &proc_res);
}

// FIXME(#41968): Move this check to tidy?
if !errors::load_errors(&self.testpaths.file, self.revision).is_empty() {
self.fatal("run-pass tests with expected warnings should be moved to ui/");
}

if let WillExecute::Disabled = should_run {
return;
}

// FIXME(#41968): Move this check to tidy?
let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
assert!(
expected_errors.is_empty(),
"run-pass tests with expected warnings should be moved to ui/"
);

let proc_res = self.exec_compiled_test();
if !proc_res.status.success() {
self.fatal_proc_rec("test run failed!", &proc_res);
Expand Down Expand Up @@ -2903,10 +2917,11 @@ impl<'test> TestCx<'test> {
fn run_incremental_test(&self) {
// Basic plan for a test incremental/foo/bar.rs:
// - load list of revisions rpass1, cfail2, rpass3
// - each should begin with `rpass`, `cfail`, or `rfail`
// - if `rpass`, expect compile and execution to succeed
// - each should begin with `cpass`, `rpass`, `cfail`, or `rfail`
// - if `cpass`, expect compilation to succeed, don't execute
// - if `rpass`, expect compilation and execution to succeed
// - if `cfail`, expect compilation to fail
// - if `rfail`, expect execution to fail
// - if `rfail`, expect compilation to succeed and execution to fail
// - create a directory build/foo/bar.incremental
// - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C rpass1
// - because name of revision starts with "rpass", expect success
Expand All @@ -2930,7 +2945,12 @@ impl<'test> TestCx<'test> {
print!("revision={:?} props={:#?}", revision, self.props);
}

if revision.starts_with("rpass") {
if revision.starts_with("cpass") {
if self.props.should_ice {
self.fatal("can only use should-ice in cfail tests");
}
self.run_cpass_test();
} else if revision.starts_with("rpass") {
if self.props.should_ice {
self.fatal("can only use should-ice in cfail tests");
}
Expand All @@ -2943,7 +2963,7 @@ impl<'test> TestCx<'test> {
} else if revision.starts_with("cfail") {
self.run_cfail_test();
} else {
self.fatal("revision name must begin with rpass, rfail, or cfail");
self.fatal("revision name must begin with cpass, rpass, rfail, or cfail");
}
}

Expand Down
10 changes: 10 additions & 0 deletions tests/incremental/auxiliary/circular-dependencies-aux.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// edition: 2021
// compile-flags: --crate-type lib --extern circular_dependencies={{build-base}}/circular-dependencies/libcircular_dependencies.rmeta --emit dep-info,metadata

use circular_dependencies::Foo;

pub fn consume_foo(_: Foo) {}

pub fn produce_foo() -> Foo {
Foo
}
37 changes: 37 additions & 0 deletions tests/incremental/circular-dependencies.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// ignore-tidy-linelength
// revisions: cpass1 cfail2
// edition: 2021
// [cpass1] compile-flags: --crate-type lib --emit dep-info,metadata
// [cfail2] aux-build: circular-dependencies-aux.rs
// [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`

pub fn consume_foo(_: Foo) {}
//[cfail2]~^ NOTE function defined here

pub fn produce_foo() -> Foo {
Foo
}

#[test]
fn test() {
aux::consume_foo(produce_foo());
//[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

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
}