mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-07 13:25:45 +00:00
Merge #1089
1089: fix a panic with glob-import missing a source map r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
2d680ff93a
@ -117,11 +117,7 @@ impl Module {
|
||||
}
|
||||
|
||||
/// Returns the syntax of the last path segment corresponding to this import
|
||||
pub fn import_source(
|
||||
&self,
|
||||
db: &impl HirDatabase,
|
||||
import: ImportId,
|
||||
) -> TreeArc<ast::PathSegment> {
|
||||
pub fn import_source(&self, db: &impl HirDatabase, import: ImportId) -> TreeArc<ast::UseTree> {
|
||||
self.import_source_impl(db, import)
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ impl Module {
|
||||
&self,
|
||||
db: &impl HirDatabase,
|
||||
import: ImportId,
|
||||
) -> TreeArc<ast::PathSegment> {
|
||||
) -> TreeArc<ast::UseTree> {
|
||||
let (file_id, source) = self.definition_source(db);
|
||||
let (_, source_map) = db.raw_items_with_source_map(file_id);
|
||||
source_map.get(&source, import)
|
||||
|
@ -31,15 +31,15 @@ pub struct RawItems {
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Eq)]
|
||||
pub struct ImportSourceMap {
|
||||
map: ArenaMap<ImportId, AstPtr<ast::PathSegment>>,
|
||||
map: ArenaMap<ImportId, AstPtr<ast::UseTree>>,
|
||||
}
|
||||
|
||||
impl ImportSourceMap {
|
||||
fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) {
|
||||
self.map.insert(import, AstPtr::new(segment))
|
||||
fn insert(&mut self, import: ImportId, use_tree: &ast::UseTree) {
|
||||
self.map.insert(import, AstPtr::new(use_tree))
|
||||
}
|
||||
|
||||
pub(crate) fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc<ast::PathSegment> {
|
||||
pub(crate) fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc<ast::UseTree> {
|
||||
let file = match source {
|
||||
ModuleSource::SourceFile(file) => &*file,
|
||||
ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(),
|
||||
@ -256,17 +256,15 @@ impl RawItemsCollector {
|
||||
fn add_use_item(&mut self, current_module: Option<Module>, use_item: &ast::UseItem) {
|
||||
let is_prelude = use_item.has_atom_attr("prelude_import");
|
||||
|
||||
Path::expand_use_item(use_item, |path, segment, alias| {
|
||||
Path::expand_use_item(use_item, |path, use_tree, is_glob, alias| {
|
||||
let import = self.raw_items.imports.alloc(ImportData {
|
||||
path,
|
||||
alias,
|
||||
is_glob: segment.is_none(),
|
||||
is_glob,
|
||||
is_prelude,
|
||||
is_extern_crate: false,
|
||||
});
|
||||
if let Some(segment) = segment {
|
||||
self.source_map.insert(import, segment)
|
||||
}
|
||||
self.source_map.insert(import, use_tree);
|
||||
self.push_item(current_module, RawItem::Import(import))
|
||||
})
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ impl Path {
|
||||
/// Calls `cb` with all paths, represented by this use item.
|
||||
pub fn expand_use_item<'a>(
|
||||
item: &'a ast::UseItem,
|
||||
mut cb: impl FnMut(Path, Option<&'a ast::PathSegment>, Option<Name>),
|
||||
mut cb: impl FnMut(Path, &'a ast::UseTree, bool, Option<Name>),
|
||||
) {
|
||||
if let Some(tree) = item.use_tree() {
|
||||
expand_use_tree(None, tree, &mut cb);
|
||||
@ -156,7 +156,7 @@ impl From<Name> for Path {
|
||||
fn expand_use_tree<'a>(
|
||||
prefix: Option<Path>,
|
||||
tree: &'a ast::UseTree,
|
||||
cb: &mut impl FnMut(Path, Option<&'a ast::PathSegment>, Option<Name>),
|
||||
cb: &mut impl FnMut(Path, &'a ast::UseTree, bool, Option<Name>),
|
||||
) {
|
||||
if let Some(use_tree_list) = tree.use_tree_list() {
|
||||
let prefix = match tree.path() {
|
||||
@ -181,18 +181,15 @@ fn expand_use_tree<'a>(
|
||||
if let Some(segment) = ast_path.segment() {
|
||||
if segment.kind() == Some(ast::PathSegmentKind::SelfKw) {
|
||||
if let Some(prefix) = prefix {
|
||||
cb(prefix, Some(segment), alias);
|
||||
cb(prefix, tree, false, alias);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(path) = convert_path(prefix, ast_path) {
|
||||
if tree.has_star() {
|
||||
cb(path, None, alias)
|
||||
} else if let Some(segment) = ast_path.segment() {
|
||||
cb(path, Some(segment), alias)
|
||||
};
|
||||
let is_glob = tree.has_star();
|
||||
cb(path, tree, is_glob, alias)
|
||||
}
|
||||
// FIXME: report errors somewhere
|
||||
// We get here if we do
|
||||
|
@ -72,6 +72,18 @@ mod tests {
|
||||
assert!(completions.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dont_complete_current_use_in_braces_with_glob() {
|
||||
let completions = do_completion(
|
||||
r"
|
||||
mod foo { pub struct S; }
|
||||
use self::{foo::*, bar<|>};
|
||||
",
|
||||
CompletionKind::Reference,
|
||||
);
|
||||
assert_eq!(completions.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completes_mod_with_docs() {
|
||||
check_reference_completion(
|
||||
|
Loading…
Reference in New Issue
Block a user