Fix various names, e.g. Iterator not resolving in core prelude

Basically, `Iterator` is re-exported via several steps, which happened to not be
resolved yet when we got to the prelude import, but since the name resolved to
the reexport from `core::iter` (just to no actual items), we gave up trying to
resolve it further.

Maybe part of the problem is that we can have
`PartialResolvedImport::Unresolved` or `PartialResolvedImport::Indeterminate`
with `None` in all namespaces, and handle them differently.

Fixes #2683.
This commit is contained in:
Florian Diebold 2020-01-11 23:19:58 +01:00
parent 2e09a96f82
commit 9dc1826cfa
3 changed files with 100 additions and 1 deletions

View File

@ -328,7 +328,7 @@ where
);
let def = res.resolved_def;
if res.reached_fixedpoint == ReachedFixedPoint::No {
if res.reached_fixedpoint == ReachedFixedPoint::No || def.is_none() {
return PartialResolvedImport::Unresolved;
}

View File

@ -52,6 +52,51 @@ fn nested_module_resolution() {
"###);
}
#[test]
fn nested_module_resolution_2() {
let map = def_map(
"
//- /lib.rs
mod prelude;
mod iter;
//- /prelude.rs
pub use crate::iter::Iterator;
//- /iter.rs
pub use self::traits::Iterator;
mod traits;
//- /iter/traits.rs
pub use self::iterator::Iterator;
mod iterator;
//- /iter/traits/iterator.rs
pub trait Iterator;
",
);
assert_snapshot!(map, @r###"
crate
iter: t
prelude: t
crate::iter
Iterator: t
traits: t
crate::iter::traits
Iterator: t
iterator: t
crate::iter::traits::iterator
Iterator: t
crate::prelude
Iterator: t
"###);
}
#[test]
fn module_resolution_works_for_non_standard_filenames() {
let map = def_map(

View File

@ -2,6 +2,8 @@ use insta::assert_snapshot;
use test_utils::covers;
use super::infer;
use crate::test_db::TestDB;
use ra_db::fixture::WithFixture;
#[test]
fn bug_484() {
@ -399,3 +401,55 @@ fn test() {
"###
);
}
#[test]
fn issue_2683_chars_impl() {
let (db, pos) = TestDB::with_position(
r#"
//- /main.rs crate:main deps:std
fn test() {
let chars: std::str::Chars<'_>;
(chars.next(), chars.nth(1))<|>;
}
//- /std.rs crate:std
#[prelude_import]
use prelude::*;
pub mod prelude {
pub use crate::iter::Iterator;
pub use crate::option::Option;
}
pub mod iter {
pub use self::traits::Iterator;
pub mod traits {
pub use self::iterator::Iterator;
pub mod iterator {
pub trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
fn nth(&mut self, n: usize) -> Option<Self::Item> {}
}
}
}
}
pub mod option {
pub enum Option<T> {}
}
pub mod str {
pub struct Chars<'a> {}
impl<'a> Iterator for Chars<'a> {
type Item = char;
fn next(&mut self) -> Option<char> {}
}
}
"#,
);
// should be Option<char>, but currently not because of Chalk ambiguity problem
assert_eq!("(Option<{unknown}>, Option<{unknown}>)", super::type_at_pos(&db, pos));
}