hir::PathKind::Abs => ps.push("".into()),
hir::PathKind::Crate => ps.push("crate".into()),
hir::PathKind::Plain => {}
- hir::PathKind::Self_ => ps.push("self".into()),
- hir::PathKind::Super => ps.push("super".into()),
+ hir::PathKind::Super(0) => ps.push("self".into()),
+ hir::PathKind::Super(lvl) => {
+ let mut chain = "super".to_string();
+ for _ in 0..*lvl {
+ chain += "::super";
+ }
+ ps.push(chain.into());
+ }
hir::PathKind::Type(_) | hir::PathKind::DollarCrate(_) => return None,
}
ps.extend(path.segments().iter().map(|it| it.name.to_string().into()));
//!
//! `ReachedFixedPoint` signals about this.
+use std::iter::successors;
+
use hir_expand::name::Name;
use ra_db::Edition;
use test_utils::tested_by;
PathKind::Crate => {
PerNs::types(ModuleId { krate: self.krate, local_id: self.root }.into())
}
- PathKind::Self_ => {
- PerNs::types(ModuleId { krate: self.krate, local_id: original_module }.into())
- }
// plain import or absolute path in 2015: crate-relative with
// fallback to extern prelude (with the simplification in
// rust-lang/rust#57745)
log::debug!("resolving {:?} in module", segment);
self.resolve_name_in_module(db, original_module, &segment, prefer_module(idx))
}
- PathKind::Super => {
- if let Some(p) = self.modules[original_module].parent {
- PerNs::types(ModuleId { krate: self.krate, local_id: p }.into())
+ // PathKind::Self_ => {
+ // PerNs::types(ModuleId { krate: self.krate, local_id: original_module }.into())
+ // }
+ // PathKind::Super => {
+ // if let Some(p) = self.modules[original_module].parent {
+ // PerNs::types(ModuleId { krate: self.krate, local_id: p }.into())
+ // } else {
+ // log::debug!("super path in root module");
+ // return ResolvePathResult::empty(ReachedFixedPoint::Yes);
+ // }
+ // }
+ PathKind::Super(lvl) => {
+ let m = successors(Some(original_module), |m| self.modules[*m].parent)
+ .nth(lvl as usize);
+ if let Some(local_id) = m {
+ PerNs::types(ModuleId { krate: self.krate, local_id }.into())
} else {
log::debug!("super path in root module");
return ResolvePathResult::empty(ReachedFixedPoint::Yes);
if module.krate != self.krate {
let path = ModPath {
segments: path.segments[i..].to_vec(),
- kind: PathKind::Self_,
+ kind: PathKind::Super(0),
};
log::debug!("resolving {:?} in other crate", path);
let defp_map = db.crate_def_map(module.krate);
}
pub fn is_self(&self) -> bool {
- self.kind == PathKind::Self_ && self.segments.is_empty()
+ self.kind == PathKind::Super(0) && self.segments.is_empty()
}
/// If this path is a single identifier, like `foo`, return its name.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum PathKind {
Plain,
- Self_,
- Super,
+ Super(u8),
Crate,
// Absolute path
Abs,
if prefix.is_some() {
return None;
}
- ModPath::from_simple_segments(PathKind::Self_, iter::empty())
+ ModPath::from_simple_segments(PathKind::Super(0), iter::empty())
}
ast::PathSegmentKind::SuperKw => {
if prefix.is_some() {
return None;
}
- ModPath::from_simple_segments(PathKind::Super, iter::empty())
+ ModPath::from_simple_segments(PathKind::Super(1), iter::empty())
}
ast::PathSegmentKind::Type { .. } => {
// not allowed in imports