Skip to content

Commit a6993d6

Browse files
committed
resolve: Fix instability in import suggestions
1 parent 5c71e4e commit a6993d6

File tree

5 files changed

+55
-74
lines changed

5 files changed

+55
-74
lines changed

src/librustc_resolve/lib.rs

+17-3
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ impl<'a> PathSource<'a> {
546546
}
547547
}
548548

549-
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
549+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
550550
pub enum Namespace {
551551
TypeNS,
552552
ValueNS,
@@ -898,6 +898,19 @@ impl<'a> ModuleData<'a> {
898898
}
899899
}
900900

901+
fn for_each_child_stable<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
902+
let resolutions = self.resolutions.borrow();
903+
let mut resolutions = resolutions.iter().map(|(&(ident, ns), &resolution)| {
904+
// Pre-compute keys for sorting
905+
(ident.name.as_str(), ns, ident, resolution)
906+
})
907+
.collect::<Vec<_>>();
908+
resolutions.sort_unstable_by_key(|&(str, ns, ..)| (str, ns));
909+
for &(_, ns, ident, resolution) in resolutions.iter() {
910+
resolution.borrow().binding.map(|binding| f(ident, ns, binding));
911+
}
912+
}
913+
901914
fn def(&self) -> Option<Def> {
902915
match self.kind {
903916
ModuleKind::Def(def, _) => Some(def),
@@ -3351,8 +3364,9 @@ impl<'a> Resolver<'a> {
33513364
in_module_is_extern)) = worklist.pop() {
33523365
self.populate_module_if_necessary(in_module);
33533366

3354-
in_module.for_each_child(|ident, ns, name_binding| {
3355-
3367+
// We have to visit module children in deterministic order to avoid
3368+
// instabilities in reported imports (#43552).
3369+
in_module.for_each_child_stable(|ident, ns, name_binding| {
33563370
// avoid imports entirely
33573371
if name_binding.is_import() && !name_binding.is_extern_crate() { return; }
33583372
// avoid non-importable candidates as well

src/libsyntax_pos/symbol.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
326326
/// destroyed. In particular, they must not access string contents. This can
327327
/// be fixed in the future by just leaking all strings until thread death
328328
/// somehow.
329-
#[derive(Clone, Hash, PartialOrd, Eq, Ord)]
329+
#[derive(Clone, Copy, Hash, PartialOrd, Eq, Ord)]
330330
pub struct InternedString {
331331
string: &'static str,
332332
}

src/test/compile-fail/issue-35675.rs

-67
This file was deleted.

src/test/ui/issue-35675.rs

+16
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,27 @@ fn should_return_fruit_too() -> Fruit::Apple {
3333
//~| NOTE not found in this scope
3434
}
3535

36+
fn foo() -> Ok {
37+
//~^ ERROR expected type, found variant `Ok`
38+
//~| NOTE not a type
39+
//~| HELP there is an enum variant
40+
//~| HELP there is an enum variant
41+
Ok(())
42+
}
43+
3644
fn bar() -> Variant3 {
3745
//~^ ERROR cannot find type `Variant3` in this scope
3846
//~| NOTE not found in this scope
3947
}
4048

49+
fn qux() -> Some {
50+
//~^ ERROR expected type, found variant `Some`
51+
//~| NOTE not a type
52+
//~| HELP there is an enum variant
53+
//~| HELP there is an enum variant
54+
Some(1)
55+
}
56+
4157
fn main() {}
4258

4359
mod x {

src/test/ui/issue-35675.stderr

+21-3
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,32 @@ help: possible candidate is found in another module, you can import it into scop
3838
12 | use Fruit::Apple;
3939
|
4040

41-
error[E0412]: cannot find type `Variant3` in this scope
41+
error[E0573]: expected type, found variant `Ok`
4242
--> $DIR/issue-35675.rs:36:13
4343
|
44-
36 | fn bar() -> Variant3 {
44+
36 | fn foo() -> Ok {
45+
| ^^ not a type
46+
|
47+
= help: there is an enum variant `std::prelude::v1::Ok`, try using `std::prelude::v1`?
48+
= help: there is an enum variant `std::result::Result::Ok`, try using `std::result::Result`?
49+
50+
error[E0412]: cannot find type `Variant3` in this scope
51+
--> $DIR/issue-35675.rs:44:13
52+
|
53+
44 | fn bar() -> Variant3 {
4554
| ^^^^^^^^
4655
| |
4756
| not found in this scope
4857
| help: you can try using the variant's enum: `x::Enum`
4958

50-
error: aborting due to 5 previous errors
59+
error[E0573]: expected type, found variant `Some`
60+
--> $DIR/issue-35675.rs:49:13
61+
|
62+
49 | fn qux() -> Some {
63+
| ^^^^ not a type
64+
|
65+
= help: there is an enum variant `std::prelude::v1::Option::Some`, try using `std::prelude::v1::Option`?
66+
= help: there is an enum variant `std::prelude::v1::Some`, try using `std::prelude::v1`?
67+
68+
error: aborting due to 7 previous errors
5169

0 commit comments

Comments
 (0)