2962: Differentiate underscore alias from named aliases r=matklad a=zombiefungus

pre for Fixing Issue 2736 
edited to avoid autoclosing the issue

Co-authored-by: zombiefungus <divmermarlav@gmail.com>
This commit is contained in:
bors[bot] 2020-02-04 09:44:31 +00:00 committed by GitHub
commit 73c36fdbd2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 14 deletions

View file

@ -22,7 +22,7 @@ use crate::{
diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode, raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode,
}, },
path::{ModPath, PathKind}, path::{ImportAlias, ModPath, PathKind},
per_ns::PerNs, per_ns::PerNs,
visibility::Visibility, visibility::Visibility,
AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern,
@ -438,7 +438,11 @@ where
} else { } else {
match import.path.segments.last() { match import.path.segments.last() {
Some(last_segment) => { Some(last_segment) => {
let name = import.alias.clone().unwrap_or_else(|| last_segment.clone()); let name = match &import.alias {
Some(ImportAlias::Alias(name)) => name.clone(),
Some(ImportAlias::Underscore) => last_segment.clone(), // FIXME rust-analyzer#2736
None => last_segment.clone(),
};
log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
// extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658

View file

@ -22,8 +22,11 @@ use ra_syntax::{
use test_utils::tested_by; use test_utils::tested_by;
use crate::{ use crate::{
attr::Attrs, db::DefDatabase, path::ModPath, visibility::RawVisibility, FileAstId, HirFileId, attr::Attrs,
InFile, db::DefDatabase,
path::{ImportAlias, ModPath},
visibility::RawVisibility,
FileAstId, HirFileId, InFile,
}; };
/// `RawItems` is a set of top-level items in a file (except for impls). /// `RawItems` is a set of top-level items in a file (except for impls).
@ -145,7 +148,7 @@ impl_arena_id!(Import);
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct ImportData { pub struct ImportData {
pub(super) path: ModPath, pub(super) path: ModPath,
pub(super) alias: Option<Name>, pub(super) alias: Option<ImportAlias>,
pub(super) is_glob: bool, pub(super) is_glob: bool,
pub(super) is_prelude: bool, pub(super) is_prelude: bool,
pub(super) is_extern_crate: bool, pub(super) is_extern_crate: bool,
@ -353,7 +356,11 @@ impl RawItemsCollector {
let path = ModPath::from_name_ref(&name_ref); let path = ModPath::from_name_ref(&name_ref);
let visibility = let visibility =
RawVisibility::from_ast_with_hygiene(extern_crate.visibility(), &self.hygiene); RawVisibility::from_ast_with_hygiene(extern_crate.visibility(), &self.hygiene);
let alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name()); let alias = extern_crate.alias().map(|a| {
a.name()
.map(|it| it.as_name())
.map_or(ImportAlias::Underscore, |a| ImportAlias::Alias(a))
});
let attrs = self.parse_attrs(&extern_crate); let attrs = self.parse_attrs(&extern_crate);
// FIXME: cfg_attr // FIXME: cfg_attr
let is_macro_use = extern_crate.has_atom_attr("macro_use"); let is_macro_use = extern_crate.has_atom_attr("macro_use");

View file

@ -34,6 +34,14 @@ pub enum PathKind {
DollarCrate(CrateId), DollarCrate(CrateId),
} }
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ImportAlias {
/// Unnamed alias, as in `use Foo as _;`
Underscore,
/// Named alias
Alias(Name),
}
impl ModPath { impl ModPath {
pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option<ModPath> { pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option<ModPath> {
lower::lower_path(path, hygiene).map(|it| it.mod_path) lower::lower_path(path, hygiene).map(|it| it.mod_path)
@ -57,7 +65,7 @@ impl ModPath {
pub(crate) fn expand_use_item( pub(crate) fn expand_use_item(
item_src: InFile<ast::UseItem>, item_src: InFile<ast::UseItem>,
hygiene: &Hygiene, hygiene: &Hygiene,
mut cb: impl FnMut(ModPath, &ast::UseTree, /* is_glob */ bool, Option<Name>), mut cb: impl FnMut(ModPath, &ast::UseTree, /* is_glob */ bool, Option<ImportAlias>),
) { ) {
if let Some(tree) = item_src.value.use_tree() { if let Some(tree) = item_src.value.use_tree() {
lower::lower_use_tree(None, tree, hygiene, &mut cb); lower::lower_use_tree(None, tree, hygiene, &mut cb);

View file

@ -4,20 +4,17 @@
use std::iter; use std::iter;
use either::Either; use either::Either;
use hir_expand::{ use hir_expand::{hygiene::Hygiene, name::AsName};
hygiene::Hygiene,
name::{AsName, Name},
};
use ra_syntax::ast::{self, NameOwner}; use ra_syntax::ast::{self, NameOwner};
use test_utils::tested_by; use test_utils::tested_by;
use crate::path::{ModPath, PathKind}; use crate::path::{ImportAlias, ModPath, PathKind};
pub(crate) fn lower_use_tree( pub(crate) fn lower_use_tree(
prefix: Option<ModPath>, prefix: Option<ModPath>,
tree: ast::UseTree, tree: ast::UseTree,
hygiene: &Hygiene, hygiene: &Hygiene,
cb: &mut dyn FnMut(ModPath, &ast::UseTree, bool, Option<Name>), cb: &mut dyn FnMut(ModPath, &ast::UseTree, bool, Option<ImportAlias>),
) { ) {
if let Some(use_tree_list) = tree.use_tree_list() { if let Some(use_tree_list) = tree.use_tree_list() {
let prefix = match tree.path() { let prefix = match tree.path() {
@ -34,7 +31,11 @@ pub(crate) fn lower_use_tree(
lower_use_tree(prefix.clone(), child_tree, hygiene, cb); lower_use_tree(prefix.clone(), child_tree, hygiene, cb);
} }
} else { } else {
let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name()); let alias = tree.alias().map(|a| {
a.name()
.map(|it| it.as_name())
.map_or(ImportAlias::Underscore, |a| ImportAlias::Alias(a))
});
let is_glob = tree.has_star(); let is_glob = tree.has_star();
if let Some(ast_path) = tree.path() { if let Some(ast_path) = tree.path() {
// Handle self in a path. // Handle self in a path.