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

Include rmeta candidates in "multiple matching crates" error #89587

Merged
merged 6 commits into from
Oct 13, 2021
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
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ E0455: include_str!("./error_codes/E0455.md"),
E0458: include_str!("./error_codes/E0458.md"),
E0459: include_str!("./error_codes/E0459.md"),
E0463: include_str!("./error_codes/E0463.md"),
E0464: include_str!("./error_codes/E0464.md"),
E0466: include_str!("./error_codes/E0466.md"),
E0468: include_str!("./error_codes/E0468.md"),
E0469: include_str!("./error_codes/E0469.md"),
Expand Down Expand Up @@ -587,7 +588,6 @@ E0785: include_str!("./error_codes/E0785.md"),
E0460, // found possibly newer version of crate `..`
E0461, // couldn't find crate `..` with expected target triple ..
E0462, // found staticlib `..` instead of rlib or dylib
E0464, // multiple matching crates for `..`
E0465, // multiple .. candidates for `..` found
// E0467, removed
// E0470, removed
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_error_codes/src/error_codes/E0464.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
The compiler found multiple library files with the requested crate name.

This error can occur in several different cases -- for example, when using
`extern crate` or passing `--extern` options without crate paths. It can also be
caused by caching issues with the build directory, in which case `cargo clean`
may help.
34 changes: 21 additions & 13 deletions compiler/rustc_metadata/src/locator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ use rustc_span::Span;
use rustc_target::spec::{Target, TargetTriple};

use snap::read::FrameDecoder;
use std::fmt::Write as _;
use std::io::{Read, Result as IoResult, Write};
use std::path::{Path, PathBuf};
use std::{cmp, fmt, fs};
Expand Down Expand Up @@ -910,23 +911,30 @@ impl CrateError {
"multiple matching crates for `{}`",
crate_name
);
let mut libraries: Vec<_> = libraries.into_values().collect();
// Make ordering of candidates deterministic.
// This has to `clone()` to work around lifetime restrictions with `sort_by_key()`.
// `sort_by()` could be used instead, but this is in the error path,
// so the performance shouldn't matter.
libraries.sort_by_cached_key(|lib| lib.source.paths().next().unwrap().clone());
let candidates = libraries
.iter()
.filter_map(|(_, lib)| {
.map(|lib| {
let crate_name = &lib.metadata.get_root().name().as_str();
camelid marked this conversation as resolved.
Show resolved Hide resolved
match (&lib.source.dylib, &lib.source.rlib) {
(Some((pd, _)), Some((pr, _))) => Some(format!(
"\ncrate `{}`: {}\n{:>padding$}",
crate_name,
pd.display(),
pr.display(),
padding = 8 + crate_name.len()
)),
(Some((p, _)), None) | (None, Some((p, _))) => {
Some(format!("\ncrate `{}`: {}", crate_name, p.display()))
}
(None, None) => None,
let mut paths = lib.source.paths();

// This `unwrap()` should be okay because there has to be at least one
// source file. `CrateSource`'s docs confirm that too.
let mut s = format!(
"\ncrate `{}`: {}",
crate_name,
paths.next().unwrap().display()
);
let padding = 8 + crate_name.len();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This padding doesn't seem correct to me. It's the same as before, but crate ` is 7 chars and `: is 3 chars (backtick, colon, space). Together, that makes 10 characters, not 8. Additionally, I don't think the format specifier {:>padding$} is correct for paths shorter than padding.

Should I change it to push_str the padding, and then push the path, rather than using format specifiers? I think that would be more correct.

for path in paths {
write!(s, "\n{:>padding$}", path.display(), padding = padding).unwrap();
}
s
})
.collect::<String>();
err.note(&format!("candidates:{}", candidates));
Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/crate-loading/auxiliary/crateresolve2-1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// compile-flags:-C extra-filename=-1 --emit=metadata
#![crate_name = "crateresolve2"]
#![crate_type = "lib"]

pub fn f() -> isize { 10 }
5 changes: 5 additions & 0 deletions src/test/ui/crate-loading/auxiliary/crateresolve2-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// compile-flags:-C extra-filename=-2 --emit=metadata
#![crate_name = "crateresolve2"]
#![crate_type = "lib"]

pub fn f() -> isize { 20 }
5 changes: 5 additions & 0 deletions src/test/ui/crate-loading/auxiliary/crateresolve2-3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// compile-flags:-C extra-filename=-3 --emit=metadata
#![crate_name = "crateresolve2"]
#![crate_type = "lib"]

pub fn f() -> isize { 30 }
9 changes: 7 additions & 2 deletions src/test/ui/crate-loading/crateresolve1.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
// dont-check-compiler-stderr
// aux-build:crateresolve1-1.rs
// aux-build:crateresolve1-2.rs
// aux-build:crateresolve1-3.rs
// error-pattern:multiple matching crates for `crateresolve1`

// normalize-stderr-test: "\.nll/" -> "/"
// normalize-stderr-test: "\\\?\\" -> ""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why doesn't this issue appear with other tests printing $TEST_BUILD_DIR paths?
Do verbatim paths (\\?) appear because the path is fs::canonicalize-d in this case?
This normalization looks like a compiletest's job (src\tools\compiletest\src\runtest.rs -> fn normalize_output).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that it's a bit odd, but I figured it's because the crate loader is showing absolute paths. I don't have time to look into whether this is a compiletest issue unfortunately.

// normalize-stderr-test: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib"

// NOTE: This test is duplicated at `src/test/ui/error-codes/E0464.rs`.

extern crate crateresolve1;
//~^ ERROR multiple matching crates for `crateresolve1`

fn main() {
}
14 changes: 14 additions & 0 deletions src/test/ui/crate-loading/crateresolve1.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0464]: multiple matching crates for `crateresolve1`
--> $DIR/crateresolve1.rs:11:1
|
LL | extern crate crateresolve1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: candidates:
crate `crateresolve1`: $TEST_BUILD_DIR/crate-loading/crateresolve1/auxiliary/libcrateresolve1-1.somelib
crate `crateresolve1`: $TEST_BUILD_DIR/crate-loading/crateresolve1/auxiliary/libcrateresolve1-2.somelib
crate `crateresolve1`: $TEST_BUILD_DIR/crate-loading/crateresolve1/auxiliary/libcrateresolve1-3.somelib

error: aborting due to previous error

For more information about this error, try `rustc --explain E0464`.
14 changes: 14 additions & 0 deletions src/test/ui/crate-loading/crateresolve2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// check-fail

// aux-build:crateresolve2-1.rs
// aux-build:crateresolve2-2.rs
// aux-build:crateresolve2-3.rs

// normalize-stderr-test: "\.nll/" -> "/"
// normalize-stderr-test: "\\\?\\" -> ""

extern crate crateresolve2;
//~^ ERROR multiple matching crates for `crateresolve2`

fn main() {
}
14 changes: 14 additions & 0 deletions src/test/ui/crate-loading/crateresolve2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0464]: multiple matching crates for `crateresolve2`
--> $DIR/crateresolve2.rs:10:1
|
LL | extern crate crateresolve2;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: candidates:
crate `crateresolve2`: $TEST_BUILD_DIR/crate-loading/crateresolve2/auxiliary/libcrateresolve2-1.rmeta
crate `crateresolve2`: $TEST_BUILD_DIR/crate-loading/crateresolve2/auxiliary/libcrateresolve2-2.rmeta
crate `crateresolve2`: $TEST_BUILD_DIR/crate-loading/crateresolve2/auxiliary/libcrateresolve2-3.rmeta

error: aborting due to previous error

For more information about this error, try `rustc --explain E0464`.
15 changes: 15 additions & 0 deletions src/test/ui/error-codes/E0464.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// aux-build:crateresolve1-1.rs
// aux-build:crateresolve1-2.rs
// aux-build:crateresolve1-3.rs

// normalize-stderr-test: "\.nll/" -> "/"
// normalize-stderr-test: "\\\?\\" -> ""
// normalize-stderr-test: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib"

// NOTE: This test is duplicated from `src/test/ui/crate-loading/crateresolve1.rs`.

extern crate crateresolve1;
//~^ ERROR multiple matching crates for `crateresolve1`

fn main() {
}
14 changes: 14 additions & 0 deletions src/test/ui/error-codes/E0464.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0464]: multiple matching crates for `crateresolve1`
--> $DIR/E0464.rs:11:1
|
LL | extern crate crateresolve1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: candidates:
crate `crateresolve1`: $TEST_BUILD_DIR/error-codes/E0464/auxiliary/libcrateresolve1-1.somelib
crate `crateresolve1`: $TEST_BUILD_DIR/error-codes/E0464/auxiliary/libcrateresolve1-2.somelib
crate `crateresolve1`: $TEST_BUILD_DIR/error-codes/E0464/auxiliary/libcrateresolve1-3.somelib

error: aborting due to previous error

For more information about this error, try `rustc --explain E0464`.
5 changes: 5 additions & 0 deletions src/test/ui/error-codes/auxiliary/crateresolve1-1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// compile-flags:-C extra-filename=-1
#![crate_name = "crateresolve1"]
#![crate_type = "lib"]

pub fn f() -> isize { 10 }
5 changes: 5 additions & 0 deletions src/test/ui/error-codes/auxiliary/crateresolve1-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// compile-flags:-C extra-filename=-2
#![crate_name = "crateresolve1"]
#![crate_type = "lib"]

pub fn f() -> isize { 20 }
5 changes: 5 additions & 0 deletions src/test/ui/error-codes/auxiliary/crateresolve1-3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// compile-flags:-C extra-filename=-3
#![crate_name = "crateresolve1"]
#![crate_type = "lib"]

pub fn f() -> isize { 30 }
petrochenkov marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 3 additions & 3 deletions src/tools/tidy/src/error_codes_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ use regex::Regex;

// A few of those error codes can't be tested but all the others can and *should* be tested!
const EXEMPTED_FROM_TEST: &[&str] = &[
"E0227", "E0279", "E0280", "E0313", "E0377", "E0461", "E0462", "E0464", "E0465", "E0476",
"E0514", "E0519", "E0523", "E0554", "E0640", "E0717", "E0729",
"E0227", "E0279", "E0280", "E0313", "E0377", "E0461", "E0462", "E0465", "E0476", "E0514",
"E0519", "E0523", "E0554", "E0640", "E0717", "E0729",
];

// Some error codes don't have any tests apparently...
const IGNORE_EXPLANATION_CHECK: &[&str] = &["E0570", "E0601", "E0602", "E0729"];
const IGNORE_EXPLANATION_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602", "E0729"];

// If the file path contains any of these, we don't want to try to extract error codes from it.
//
Expand Down