From 5d99ba1d9a5acf02a5cd50e456f164bd80b523b5 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 4 Feb 2021 20:49:24 +0100 Subject: Make `ModPath`'s representation private --- crates/hir_def/src/find_path.rs | 10 ++++----- crates/hir_def/src/item_tree.rs | 8 +++----- crates/hir_def/src/item_tree/lower.rs | 3 ++- crates/hir_def/src/lib.rs | 2 +- crates/hir_def/src/nameres/collector.rs | 4 ++-- crates/hir_def/src/nameres/path_resolution.rs | 20 +++++++++--------- crates/hir_def/src/path.rs | 29 +++++++++++++++++++++++---- crates/hir_def/src/resolver.rs | 12 +++++------ crates/hir_def/src/visibility.rs | 9 ++++----- 9 files changed, 58 insertions(+), 39 deletions(-) (limited to 'crates/hir_def/src') diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs index 94a1d567d..aa2c6e04e 100644 --- a/crates/hir_def/src/find_path.rs +++ b/crates/hir_def/src/find_path.rs @@ -36,13 +36,13 @@ const MAX_PATH_LEN: usize = 15; impl ModPath { fn starts_with_std(&self) -> bool { - self.segments.first() == Some(&known::std) + self.segments().first() == Some(&known::std) } // When std library is present, paths starting with `std::` // should be preferred over paths starting with `core::` and `alloc::` fn can_start_with_std(&self) -> bool { - let first_segment = self.segments.first(); + let first_segment = self.segments().first(); first_segment == Some(&known::alloc) || first_segment == Some(&known::core) } } @@ -157,7 +157,7 @@ fn find_path_inner( if let Some(ModuleDefId::EnumVariantId(variant)) = item.as_module_def_id() { if let Some(mut path) = find_path(db, ItemInNs::Types(variant.parent.into()), from) { let data = db.enum_data(variant.parent); - path.segments.push(data.variants[variant.local_id].name.clone()); + path.push_segment(data.variants[variant.local_id].name.clone()); return Some(path); } // If this doesn't work, it seems we have no way of referring to the @@ -186,7 +186,7 @@ fn find_path_inner( best_path_len - 1, prefixed, ) { - path.segments.push(name); + path.push_segment(name); let new_path = if let Some(best_path) = best_path { select_best_path(best_path, path, prefer_no_std) @@ -215,7 +215,7 @@ fn find_path_inner( prefixed, )?; mark::hit!(partially_imported); - path.segments.push(info.path.segments.last().unwrap().clone()); + path.push_segment(info.path.segments.last().unwrap().clone()); Some(path) }) }); diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 401556931..3233b1957 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -240,7 +240,7 @@ impl ItemVisibilities { fn alloc(&mut self, vis: RawVisibility) -> RawVisibilityId { match &vis { RawVisibility::Public => RawVisibilityId::PUB, - RawVisibility::Module(path) if path.segments.is_empty() => match &path.kind { + RawVisibility::Module(path) if path.segments().is_empty() => match &path.kind { PathKind::Super(0) => RawVisibilityId::PRIV, PathKind::Crate => RawVisibilityId::PUB_CRATE, _ => RawVisibilityId(self.arena.alloc(vis).into_raw().into()), @@ -251,10 +251,8 @@ impl ItemVisibilities { } static VIS_PUB: RawVisibility = RawVisibility::Public; -static VIS_PRIV: RawVisibility = - RawVisibility::Module(ModPath { kind: PathKind::Super(0), segments: Vec::new() }); -static VIS_PUB_CRATE: RawVisibility = - RawVisibility::Module(ModPath { kind: PathKind::Crate, segments: Vec::new() }); +static VIS_PRIV: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Super(0))); +static VIS_PUB_CRATE: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Crate)); #[derive(Default, Debug, Eq, PartialEq)] struct GenericParamsStorage { diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 93cdca55d..8f2f0b340 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -750,7 +750,8 @@ impl Ctx { fn desugar_future_path(orig: TypeRef) -> Path { let path = path![core::future::Future]; - let mut generic_args: Vec<_> = std::iter::repeat(None).take(path.segments.len() - 1).collect(); + let mut generic_args: Vec<_> = + std::iter::repeat(None).take(path.segments().len() - 1).collect(); let mut last = GenericArgs::empty(); let binding = AssociatedTypeBinding { name: name![Output], type_ref: Some(orig), bounds: Vec::new() }; diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 5dd3705b0..b50923747 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs @@ -662,7 +662,7 @@ impl AsMacroCall for AstIdWithPath { def.as_lazy_macro( db.upcast(), krate, - MacroCallKind::Attr(self.ast_id, self.path.segments.last()?.to_string()), + MacroCallKind::Attr(self.ast_id, self.path.segments().last()?.to_string()), ) .into(), ) diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index f904a97de..6bd41bc08 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -655,7 +655,7 @@ impl DefCollector<'_> { } } } else { - match import.path.segments.last() { + match import.path.segments().last() { Some(last_segment) => { let name = match &import.alias { Some(ImportAlias::Alias(name)) => Some(name.clone()), @@ -956,7 +956,7 @@ impl DefCollector<'_> { let item_tree = self.db.item_tree(import.file_id); let import_data = &item_tree[import.value]; - match (import_data.path.segments.first(), &import_data.path.kind) { + match (import_data.path.segments().first(), &import_data.path.kind) { (Some(krate), PathKind::Plain) | (Some(krate), PathKind::Abs) => { if diagnosed_extern_crates.contains(krate) { continue; diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs index 2a3ac5d7b..f2b59172d 100644 --- a/crates/hir_def/src/nameres/path_resolution.rs +++ b/crates/hir_def/src/nameres/path_resolution.rs @@ -149,7 +149,7 @@ impl DefMap { path: &ModPath, shadow: BuiltinShadowMode, ) -> ResolvePathResult { - let mut segments = path.segments.iter().enumerate(); + let mut segments = path.segments().iter().enumerate(); let mut curr_per_ns: PerNs = match path.kind { PathKind::DollarCrate(krate) => { if krate == self.krate { @@ -190,7 +190,7 @@ impl DefMap { // BuiltinShadowMode wasn't Module, then we need to try // resolving it as a builtin. let prefer_module = - if path.segments.len() == 1 { shadow } else { BuiltinShadowMode::Module }; + if path.segments().len() == 1 { shadow } else { BuiltinShadowMode::Module }; log::debug!("resolving {:?} in module", segment); self.resolve_name_in_module(db, original_module, &segment, prefer_module) @@ -203,10 +203,10 @@ impl DefMap { None => match &self.block { Some(block) => { // Look up remaining path in parent `DefMap` - let new_path = ModPath { - kind: PathKind::Super(lvl - i), - segments: path.segments.clone(), - }; + let new_path = ModPath::from_segments( + PathKind::Super(lvl - i), + path.segments().to_vec(), + ); log::debug!("`super` path: {} -> {} in parent map", path, new_path); return block.parent.def_map(db).resolve_path_fp_with_macro( db, @@ -258,10 +258,10 @@ impl DefMap { curr_per_ns = match curr { ModuleDefId::ModuleId(module) => { if module.krate != self.krate { - let path = ModPath { - segments: path.segments[i..].to_vec(), - kind: PathKind::Super(0), - }; + let path = ModPath::from_segments( + PathKind::Super(0), + path.segments()[i..].iter().cloned(), + ); log::debug!("resolving {:?} in other crate", path); let defp_map = module.def_map(db); let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow); diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs index 84ea09b53..0caad53d3 100644 --- a/crates/hir_def/src/path.rs +++ b/crates/hir_def/src/path.rs @@ -20,7 +20,7 @@ use crate::{ #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct ModPath { pub kind: PathKind, - pub segments: Vec, + segments: Vec, } #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -53,6 +53,11 @@ impl ModPath { ModPath { kind, segments } } + /// Creates a `ModPath` from a `PathKind`, with no extra path segments. + pub const fn from_kind(kind: PathKind) -> ModPath { + ModPath { kind, segments: Vec::new() } + } + /// Calls `cb` with all paths, represented by this use item. pub(crate) fn expand_use_item( item_src: InFile, @@ -64,6 +69,18 @@ impl ModPath { } } + pub fn segments(&self) -> &[Name] { + &self.segments + } + + pub fn push_segment(&mut self, segment: Name) { + self.segments.push(segment); + } + + pub fn pop_segment(&mut self) -> Option { + self.segments.pop() + } + /// Returns the number of segments in the path (counting special segments like `$crate` and /// `super`). pub fn len(&self) -> usize { @@ -78,7 +95,7 @@ impl ModPath { } pub fn is_ident(&self) -> bool { - self.kind == PathKind::Plain && self.segments.len() == 1 + self.as_ident().is_some() } pub fn is_self(&self) -> bool { @@ -87,10 +104,14 @@ impl ModPath { /// If this path is a single identifier, like `foo`, return its name. pub fn as_ident(&self) -> Option<&Name> { - if !self.is_ident() { + if self.kind != PathKind::Plain { return None; } - self.segments.first() + + match &*self.segments { + [name] => Some(name), + _ => None, + } } } diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs index 9021ea712..f9ad50301 100644 --- a/crates/hir_def/src/resolver.rs +++ b/crates/hir_def/src/resolver.rs @@ -164,7 +164,7 @@ impl Resolver { db: &dyn DefDatabase, path: &ModPath, ) -> Option<(TypeNs, Option)> { - let first_name = path.segments.first()?; + let first_name = path.segments().first()?; let skip_to_mod = path.kind != PathKind::Plain; for scope in self.scopes.iter().rev() { match scope { @@ -179,7 +179,7 @@ impl Resolver { Scope::GenericParams { params, def } => { if let Some(local_id) = params.find_type_by_name(first_name) { - let idx = if path.segments.len() == 1 { None } else { Some(1) }; + let idx = if path.segments().len() == 1 { None } else { Some(1) }; return Some(( TypeNs::GenericParam(TypeParamId { local_id, parent: *def }), idx, @@ -188,13 +188,13 @@ impl Resolver { } Scope::ImplDefScope(impl_) => { if first_name == &name![Self] { - let idx = if path.segments.len() == 1 { None } else { Some(1) }; + let idx = if path.segments().len() == 1 { None } else { Some(1) }; return Some((TypeNs::SelfType(*impl_), idx)); } } Scope::AdtScope(adt) => { if first_name == &name![Self] { - let idx = if path.segments.len() == 1 { None } else { Some(1) }; + let idx = if path.segments().len() == 1 { None } else { Some(1) }; return Some((TypeNs::AdtSelfType(*adt), idx)); } } @@ -270,9 +270,9 @@ impl Resolver { db: &dyn DefDatabase, path: &ModPath, ) -> Option { - let n_segments = path.segments.len(); + let n_segments = path.segments().len(); let tmp = name![self]; - let first_name = if path.is_self() { &tmp } else { path.segments.first()? }; + let first_name = if path.is_self() { &tmp } else { path.segments().first()? }; let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); for scope in self.scopes.iter().rev() { match scope { diff --git a/crates/hir_def/src/visibility.rs b/crates/hir_def/src/visibility.rs index e79a91102..38da3132b 100644 --- a/crates/hir_def/src/visibility.rs +++ b/crates/hir_def/src/visibility.rs @@ -22,8 +22,7 @@ pub enum RawVisibility { impl RawVisibility { pub(crate) const fn private() -> RawVisibility { - let path = ModPath { kind: PathKind::Super(0), segments: Vec::new() }; - RawVisibility::Module(path) + RawVisibility::Module(ModPath::from_kind(PathKind::Super(0))) } pub(crate) fn from_ast( @@ -59,15 +58,15 @@ impl RawVisibility { RawVisibility::Module(path) } ast::VisibilityKind::PubCrate => { - let path = ModPath { kind: PathKind::Crate, segments: Vec::new() }; + let path = ModPath::from_kind(PathKind::Crate); RawVisibility::Module(path) } ast::VisibilityKind::PubSuper => { - let path = ModPath { kind: PathKind::Super(1), segments: Vec::new() }; + let path = ModPath::from_kind(PathKind::Super(1)); RawVisibility::Module(path) } ast::VisibilityKind::PubSelf => { - let path = ModPath { kind: PathKind::Plain, segments: Vec::new() }; + let path = ModPath::from_kind(PathKind::Plain); RawVisibility::Module(path) } ast::VisibilityKind::Pub => RawVisibility::Public, -- cgit v1.2.3