Refactor how global paths are represented (for both ast and hir).
This commit is contained in:
parent
164619a8cf
commit
f10f50b426
27 changed files with 242 additions and 257 deletions
|
@ -81,7 +81,7 @@ pub struct LoweringContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Resolver {
|
pub trait Resolver {
|
||||||
// Resolve a global hir path generated by the lowerer when expanding `for`, `if let`, etc.
|
// Resolve a hir path generated by the lowerer when expanding `for`, `if let`, etc.
|
||||||
fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool);
|
fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool);
|
||||||
|
|
||||||
// Obtain the resolution for a node id
|
// Obtain the resolution for a node id
|
||||||
|
@ -337,7 +337,6 @@ impl<'a> LoweringContext<'a> {
|
||||||
|
|
||||||
let proj_start = p.segments.len() - resolution.depth;
|
let proj_start = p.segments.len() - resolution.depth;
|
||||||
let path = P(hir::Path {
|
let path = P(hir::Path {
|
||||||
global: p.global,
|
|
||||||
def: resolution.base_def,
|
def: resolution.base_def,
|
||||||
segments: p.segments[..proj_start].iter().enumerate().map(|(i, segment)| {
|
segments: p.segments[..proj_start].iter().enumerate().map(|(i, segment)| {
|
||||||
let param_mode = match (qself_position, param_mode) {
|
let param_mode = match (qself_position, param_mode) {
|
||||||
|
@ -404,12 +403,17 @@ impl<'a> LoweringContext<'a> {
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
p: &Path,
|
p: &Path,
|
||||||
name: Option<Name>,
|
name: Option<Name>,
|
||||||
param_mode: ParamMode)
|
param_mode: ParamMode,
|
||||||
|
defaults_to_global: bool)
|
||||||
-> hir::Path {
|
-> hir::Path {
|
||||||
|
let mut segments = p.segments.iter();
|
||||||
|
if defaults_to_global && p.is_global() {
|
||||||
|
segments.next();
|
||||||
|
}
|
||||||
|
|
||||||
hir::Path {
|
hir::Path {
|
||||||
global: p.global,
|
|
||||||
def: self.expect_full_def(id),
|
def: self.expect_full_def(id),
|
||||||
segments: p.segments.iter().map(|segment| {
|
segments: segments.map(|segment| {
|
||||||
self.lower_path_segment(segment, param_mode)
|
self.lower_path_segment(segment, param_mode)
|
||||||
}).chain(name.map(|name| {
|
}).chain(name.map(|name| {
|
||||||
hir::PathSegment {
|
hir::PathSegment {
|
||||||
|
@ -424,9 +428,10 @@ impl<'a> LoweringContext<'a> {
|
||||||
fn lower_path(&mut self,
|
fn lower_path(&mut self,
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
p: &Path,
|
p: &Path,
|
||||||
param_mode: ParamMode)
|
param_mode: ParamMode,
|
||||||
|
defaults_to_global: bool)
|
||||||
-> hir::Path {
|
-> hir::Path {
|
||||||
self.lower_path_extra(id, p, None, param_mode)
|
self.lower_path_extra(id, p, None, param_mode, defaults_to_global)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_path_segment(&mut self,
|
fn lower_path_segment(&mut self,
|
||||||
|
@ -602,8 +607,8 @@ impl<'a> LoweringContext<'a> {
|
||||||
// Check if the where clause type is a plain type parameter.
|
// Check if the where clause type is a plain type parameter.
|
||||||
match bound_pred.bounded_ty.node {
|
match bound_pred.bounded_ty.node {
|
||||||
TyKind::Path(None, ref path)
|
TyKind::Path(None, ref path)
|
||||||
if !path.global && path.segments.len() == 1 &&
|
if path.segments.len() == 1 &&
|
||||||
bound_pred.bound_lifetimes.is_empty() => {
|
bound_pred.bound_lifetimes.is_empty() => {
|
||||||
if let Some(Def::TyParam(def_id)) =
|
if let Some(Def::TyParam(def_id)) =
|
||||||
self.resolver.get_resolution(bound_pred.bounded_ty.id)
|
self.resolver.get_resolution(bound_pred.bounded_ty.id)
|
||||||
.map(|d| d.base_def) {
|
.map(|d| d.base_def) {
|
||||||
|
@ -677,7 +682,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
span}) => {
|
span}) => {
|
||||||
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
|
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
|
||||||
id: id,
|
id: id,
|
||||||
path: self.lower_path(id, path, ParamMode::Explicit),
|
path: self.lower_path(id, path, ParamMode::Explicit, false),
|
||||||
ty: self.lower_ty(ty),
|
ty: self.lower_ty(ty),
|
||||||
span: span,
|
span: span,
|
||||||
})
|
})
|
||||||
|
@ -707,7 +712,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
|
|
||||||
fn lower_trait_ref(&mut self, p: &TraitRef) -> hir::TraitRef {
|
fn lower_trait_ref(&mut self, p: &TraitRef) -> hir::TraitRef {
|
||||||
hir::TraitRef {
|
hir::TraitRef {
|
||||||
path: self.lower_path(p.ref_id, &p.path, ParamMode::Explicit),
|
path: self.lower_path(p.ref_id, &p.path, ParamMode::Explicit, false),
|
||||||
ref_id: p.ref_id,
|
ref_id: p.ref_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -800,7 +805,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut path = self.lower_path_extra(import.id, path, suffix,
|
let mut path = self.lower_path_extra(import.id, path, suffix,
|
||||||
ParamMode::Explicit);
|
ParamMode::Explicit, true);
|
||||||
path.span = span;
|
path.span = span;
|
||||||
self.items.insert(import.id, hir::Item {
|
self.items.insert(import.id, hir::Item {
|
||||||
id: import.id,
|
id: import.id,
|
||||||
|
@ -814,7 +819,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let path = P(self.lower_path(id, path, ParamMode::Explicit));
|
let path = P(self.lower_path(id, path, ParamMode::Explicit, true));
|
||||||
let kind = match view_path.node {
|
let kind = match view_path.node {
|
||||||
ViewPathSimple(ident, _) => {
|
ViewPathSimple(ident, _) => {
|
||||||
*name = ident.name;
|
*name = ident.name;
|
||||||
|
@ -1135,7 +1140,6 @@ impl<'a> LoweringContext<'a> {
|
||||||
Some(def) => {
|
Some(def) => {
|
||||||
hir::PatKind::Path(hir::QPath::Resolved(None, P(hir::Path {
|
hir::PatKind::Path(hir::QPath::Resolved(None, P(hir::Path {
|
||||||
span: pth1.span,
|
span: pth1.span,
|
||||||
global: false,
|
|
||||||
def: def,
|
def: def,
|
||||||
segments: hir_vec![
|
segments: hir_vec![
|
||||||
hir::PathSegment::from_name(pth1.node.name)
|
hir::PathSegment::from_name(pth1.node.name)
|
||||||
|
@ -1878,7 +1882,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
Visibility::Crate(_) => hir::Visibility::Crate,
|
Visibility::Crate(_) => hir::Visibility::Crate,
|
||||||
Visibility::Restricted { ref path, id } => {
|
Visibility::Restricted { ref path, id } => {
|
||||||
hir::Visibility::Restricted {
|
hir::Visibility::Restricted {
|
||||||
path: P(self.lower_path(id, path, ParamMode::Explicit)),
|
path: P(self.lower_path(id, path, ParamMode::Explicit, true)),
|
||||||
id: id
|
id: id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1971,7 +1975,6 @@ impl<'a> LoweringContext<'a> {
|
||||||
|
|
||||||
let expr_path = hir::ExprPath(hir::QPath::Resolved(None, P(hir::Path {
|
let expr_path = hir::ExprPath(hir::QPath::Resolved(None, P(hir::Path {
|
||||||
span: span,
|
span: span,
|
||||||
global: false,
|
|
||||||
def: def,
|
def: def,
|
||||||
segments: hir_vec![hir::PathSegment::from_name(id)],
|
segments: hir_vec![hir::PathSegment::from_name(id)],
|
||||||
})));
|
})));
|
||||||
|
@ -2139,17 +2142,12 @@ impl<'a> LoweringContext<'a> {
|
||||||
/// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
|
/// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
|
||||||
/// The path is also resolved according to `is_value`.
|
/// The path is also resolved according to `is_value`.
|
||||||
fn std_path(&mut self, span: Span, components: &[&str], is_value: bool) -> hir::Path {
|
fn std_path(&mut self, span: Span, components: &[&str], is_value: bool) -> hir::Path {
|
||||||
let idents = self.crate_root.iter().chain(components);
|
|
||||||
|
|
||||||
let segments: Vec<_> = idents.map(|name| {
|
|
||||||
hir::PathSegment::from_name(Symbol::intern(name))
|
|
||||||
}).collect();
|
|
||||||
|
|
||||||
let mut path = hir::Path {
|
let mut path = hir::Path {
|
||||||
span: span,
|
span: span,
|
||||||
global: true,
|
|
||||||
def: Def::Err,
|
def: Def::Err,
|
||||||
segments: segments.into(),
|
segments: iter::once(keywords::CrateRoot.name()).chain({
|
||||||
|
self.crate_root.into_iter().chain(components.iter().cloned()).map(Symbol::intern)
|
||||||
|
}).map(hir::PathSegment::from_name).collect(),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.resolver.resolve_hir_path(&mut path, is_value);
|
self.resolver.resolve_hir_path(&mut path, is_value);
|
||||||
|
|
|
@ -105,15 +105,18 @@ pub struct LifetimeDef {
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
||||||
pub struct Path {
|
pub struct Path {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
/// A `::foo` path, is relative to the crate root rather than current
|
|
||||||
/// module (like paths in an import).
|
|
||||||
pub global: bool,
|
|
||||||
/// The definition that the path resolved to.
|
/// The definition that the path resolved to.
|
||||||
pub def: Def,
|
pub def: Def,
|
||||||
/// The segments in the path: the things separated by `::`.
|
/// The segments in the path: the things separated by `::`.
|
||||||
pub segments: HirVec<PathSegment>,
|
pub segments: HirVec<PathSegment>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Path {
|
||||||
|
pub fn is_global(&self) -> bool {
|
||||||
|
!self.segments.is_empty() && self.segments[0].name == keywords::CrateRoot.name()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Path {
|
impl fmt::Debug for Path {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "path({})", print::path_to_string(self))
|
write!(f, "path({})", print::path_to_string(self))
|
||||||
|
|
|
@ -1643,17 +1643,14 @@ impl<'a> State<'a> {
|
||||||
-> io::Result<()> {
|
-> io::Result<()> {
|
||||||
self.maybe_print_comment(path.span.lo)?;
|
self.maybe_print_comment(path.span.lo)?;
|
||||||
|
|
||||||
let mut first = !path.global;
|
for (i, segment) in path.segments.iter().enumerate() {
|
||||||
for segment in &path.segments {
|
if i > 0 {
|
||||||
if first {
|
|
||||||
first = false
|
|
||||||
} else {
|
|
||||||
word(&mut self.s, "::")?
|
word(&mut self.s, "::")?
|
||||||
}
|
}
|
||||||
|
if segment.name != keywords::CrateRoot.name() {
|
||||||
self.print_name(segment.name)?;
|
self.print_name(segment.name)?;
|
||||||
|
self.print_path_parameters(&segment.parameters, colons_before_params)?;
|
||||||
self.print_path_parameters(&segment.parameters, colons_before_params)?;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1673,15 +1670,14 @@ impl<'a> State<'a> {
|
||||||
space(&mut self.s)?;
|
space(&mut self.s)?;
|
||||||
self.word_space("as")?;
|
self.word_space("as")?;
|
||||||
|
|
||||||
let mut first = !path.global;
|
for (i, segment) in path.segments[..path.segments.len() - 1].iter().enumerate() {
|
||||||
for segment in &path.segments[..path.segments.len() - 1] {
|
if i > 0 {
|
||||||
if first {
|
|
||||||
first = false
|
|
||||||
} else {
|
|
||||||
word(&mut self.s, "::")?
|
word(&mut self.s, "::")?
|
||||||
}
|
}
|
||||||
self.print_name(segment.name)?;
|
if segment.name != keywords::CrateRoot.name() {
|
||||||
self.print_path_parameters(&segment.parameters, colons_before_params)?;
|
self.print_name(segment.name)?;
|
||||||
|
self.print_path_parameters(&segment.parameters, colons_before_params)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
word(&mut self.s, ">")?;
|
word(&mut self.s, ">")?;
|
||||||
|
|
|
@ -1620,7 +1620,6 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
|
||||||
new_segs.push(new_seg);
|
new_segs.push(new_seg);
|
||||||
hir::Path {
|
hir::Path {
|
||||||
span: path.span,
|
span: path.span,
|
||||||
global: path.global,
|
|
||||||
def: path.def,
|
def: path.def,
|
||||||
segments: new_segs.into()
|
segments: new_segs.into()
|
||||||
}
|
}
|
||||||
|
|
|
@ -324,7 +324,6 @@ impl Witness {
|
||||||
let v = ctor.variant_for_adt(adt);
|
let v = ctor.variant_for_adt(adt);
|
||||||
let qpath = hir::QPath::Resolved(None, P(hir::Path {
|
let qpath = hir::QPath::Resolved(None, P(hir::Path {
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
global: false,
|
|
||||||
def: Def::Err,
|
def: Def::Err,
|
||||||
segments: vec![hir::PathSegment::from_name(v.name)].into(),
|
segments: vec![hir::PathSegment::from_name(v.name)].into(),
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -189,7 +189,6 @@ enum SawAbiComponent<'a> {
|
||||||
SawStructField,
|
SawStructField,
|
||||||
SawVariant,
|
SawVariant,
|
||||||
SawQPath,
|
SawQPath,
|
||||||
SawPath(bool),
|
|
||||||
SawPathSegment,
|
SawPathSegment,
|
||||||
SawPathParameters,
|
SawPathParameters,
|
||||||
SawBlock,
|
SawBlock,
|
||||||
|
@ -678,7 +677,6 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has
|
||||||
|
|
||||||
fn visit_path(&mut self, path: &'tcx Path, _: ast::NodeId) {
|
fn visit_path(&mut self, path: &'tcx Path, _: ast::NodeId) {
|
||||||
debug!("visit_path: st={:?}", self.st);
|
debug!("visit_path: st={:?}", self.st);
|
||||||
SawPath(path.global).hash(self.st);
|
|
||||||
hash_span!(self, path.span);
|
hash_span!(self, path.span);
|
||||||
visit::walk_path(self, path)
|
visit::walk_path(self, path)
|
||||||
}
|
}
|
||||||
|
|
|
@ -382,7 +382,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals {
|
||||||
fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
|
fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
|
||||||
// Lint for constants that look like binding identifiers (#7526)
|
// Lint for constants that look like binding identifiers (#7526)
|
||||||
if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.node {
|
if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.node {
|
||||||
if !path.global && path.segments.len() == 1 && path.segments[0].parameters.is_empty() {
|
if path.segments.len() == 1 && path.segments[0].parameters.is_empty() {
|
||||||
if let Def::Const(..) = path.def {
|
if let Def::Const(..) = path.def {
|
||||||
NonUpperCaseGlobals::check_upper_case(cx,
|
NonUpperCaseGlobals::check_upper_case(cx,
|
||||||
"constant in pattern",
|
"constant in pattern",
|
||||||
|
|
|
@ -154,8 +154,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_path(&mut self, path: &'a Path, id: NodeId) {
|
fn visit_path(&mut self, path: &'a Path, id: NodeId) {
|
||||||
if path.global && path.segments.len() > 0 {
|
if path.segments.len() >= 2 && path.is_global() {
|
||||||
let ident = path.segments[0].identifier;
|
let ident = path.segments[1].identifier;
|
||||||
if token::Ident(ident).is_path_segment_keyword() {
|
if token::Ident(ident).is_path_segment_keyword() {
|
||||||
self.session.add_lint(lint::builtin::SUPER_OR_SELF_IN_GLOBAL_PATH,
|
self.session.add_lint(lint::builtin::SUPER_OR_SELF_IN_GLOBAL_PATH,
|
||||||
id,
|
id,
|
||||||
|
|
|
@ -40,6 +40,7 @@ use syntax::ext::base::Determinacy::Undetermined;
|
||||||
use syntax::ext::expand::mark_tts;
|
use syntax::ext::expand::mark_tts;
|
||||||
use syntax::ext::hygiene::Mark;
|
use syntax::ext::hygiene::Mark;
|
||||||
use syntax::ext::tt::macro_rules;
|
use syntax::ext::tt::macro_rules;
|
||||||
|
use syntax::parse::token;
|
||||||
use syntax::symbol::keywords;
|
use syntax::symbol::keywords;
|
||||||
use syntax::visit::{self, Visitor};
|
use syntax::visit::{self, Visitor};
|
||||||
|
|
||||||
|
@ -112,7 +113,7 @@ impl<'a> Resolver<'a> {
|
||||||
// Extract and intern the module part of the path. For
|
// Extract and intern the module part of the path. For
|
||||||
// globs and lists, the path is found directly in the AST;
|
// globs and lists, the path is found directly in the AST;
|
||||||
// for simple paths we have to munge the path a little.
|
// for simple paths we have to munge the path a little.
|
||||||
let module_path: Vec<_> = match view_path.node {
|
let mut module_path: Vec<_> = match view_path.node {
|
||||||
ViewPathSimple(_, ref full_path) => {
|
ViewPathSimple(_, ref full_path) => {
|
||||||
full_path.segments
|
full_path.segments
|
||||||
.split_last()
|
.split_last()
|
||||||
|
@ -132,6 +133,12 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This can be removed once warning cycle #36888 is complete.
|
||||||
|
if module_path.len() >= 2 && module_path[0].name == keywords::CrateRoot.name() &&
|
||||||
|
token::Ident(module_path[1]).is_path_segment_keyword() {
|
||||||
|
module_path.remove(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Build up the import directives.
|
// Build up the import directives.
|
||||||
let is_prelude = attr::contains_name(&item.attrs, "prelude_import");
|
let is_prelude = attr::contains_name(&item.attrs, "prelude_import");
|
||||||
|
|
||||||
|
@ -193,18 +200,16 @@ impl<'a> Resolver<'a> {
|
||||||
let rename = node.rename.unwrap_or(node.name);
|
let rename = node.rename.unwrap_or(node.name);
|
||||||
(module_path.clone(), node.name, rename)
|
(module_path.clone(), node.name, rename)
|
||||||
} else {
|
} else {
|
||||||
let ident = match module_path.last() {
|
let ident = *module_path.last().unwrap();
|
||||||
Some(&ident) => ident,
|
if ident.name == keywords::CrateRoot.name() {
|
||||||
None => {
|
resolve_error(
|
||||||
resolve_error(
|
self,
|
||||||
self,
|
source_item.span,
|
||||||
source_item.span,
|
ResolutionError::
|
||||||
ResolutionError::
|
SelfImportOnlyInImportListWithNonEmptyPrefix
|
||||||
SelfImportOnlyInImportListWithNonEmptyPrefix
|
);
|
||||||
);
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
let module_path = module_path.split_last().unwrap().1;
|
let module_path = module_path.split_last().unwrap().1;
|
||||||
let rename = node.rename.unwrap_or(ident);
|
let rename = node.rename.unwrap_or(ident);
|
||||||
(module_path.to_vec(), ident, rename)
|
(module_path.to_vec(), ident, rename)
|
||||||
|
|
|
@ -578,9 +578,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
||||||
fn visit_poly_trait_ref(&mut self,
|
fn visit_poly_trait_ref(&mut self,
|
||||||
tref: &'tcx ast::PolyTraitRef,
|
tref: &'tcx ast::PolyTraitRef,
|
||||||
m: &'tcx ast::TraitBoundModifier) {
|
m: &'tcx ast::TraitBoundModifier) {
|
||||||
let ast::Path { ref segments, span, global } = tref.trait_ref.path;
|
let ast::Path { ref segments, span } = tref.trait_ref.path;
|
||||||
let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
|
let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
|
||||||
let def = self.resolve_trait_reference(&path, global, None, span);
|
let def = self.resolve_trait_reference(&path, None, span);
|
||||||
self.record_def(tref.trait_ref.ref_id, def);
|
self.record_def(tref.trait_ref.ref_id, def);
|
||||||
visit::walk_poly_trait_ref(self, tref, m);
|
visit::walk_poly_trait_ref(self, tref, m);
|
||||||
}
|
}
|
||||||
|
@ -753,13 +753,6 @@ impl<'a> LexicalScopeBinding<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
|
||||||
enum PathScope {
|
|
||||||
Global,
|
|
||||||
Lexical,
|
|
||||||
Import,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
enum PathResult<'a> {
|
enum PathResult<'a> {
|
||||||
Module(Module<'a>),
|
Module(Module<'a>),
|
||||||
|
@ -783,7 +776,7 @@ pub struct ModuleData<'a> {
|
||||||
|
|
||||||
resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
|
resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
|
||||||
legacy_macro_resolutions: RefCell<Vec<(Mark, Ident, Span)>>,
|
legacy_macro_resolutions: RefCell<Vec<(Mark, Ident, Span)>>,
|
||||||
macro_resolutions: RefCell<Vec<(Box<[Ident]>, PathScope, Span)>>,
|
macro_resolutions: RefCell<Vec<(Box<[Ident]>, Span)>>,
|
||||||
|
|
||||||
// Macro invocations that can expand into items in this module.
|
// Macro invocations that can expand into items in this module.
|
||||||
unresolved_invocations: RefCell<FxHashSet<Mark>>,
|
unresolved_invocations: RefCell<FxHashSet<Mark>>,
|
||||||
|
@ -1174,13 +1167,12 @@ impl<'a> ty::NodeIdTree for Resolver<'a> {
|
||||||
impl<'a> hir::lowering::Resolver for Resolver<'a> {
|
impl<'a> hir::lowering::Resolver for Resolver<'a> {
|
||||||
fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool) {
|
fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool) {
|
||||||
let namespace = if is_value { ValueNS } else { TypeNS };
|
let namespace = if is_value { ValueNS } else { TypeNS };
|
||||||
let hir::Path { ref segments, span, global, ref mut def } = *path;
|
let hir::Path { ref segments, span, ref mut def } = *path;
|
||||||
let path: Vec<_> = segments.iter().map(|seg| Ident::with_empty_ctxt(seg.name)).collect();
|
let path: Vec<_> = segments.iter().map(|seg| Ident::with_empty_ctxt(seg.name)).collect();
|
||||||
let scope = if global { PathScope::Global } else { PathScope::Lexical };
|
match self.resolve_path(&path, Some(namespace), Some(span)) {
|
||||||
match self.resolve_path(&path, scope, Some(namespace), Some(span)) {
|
|
||||||
PathResult::Module(module) => *def = module.def().unwrap(),
|
PathResult::Module(module) => *def = module.def().unwrap(),
|
||||||
PathResult::NonModule(path_res) if path_res.depth == 0 => *def = path_res.base_def,
|
PathResult::NonModule(path_res) if path_res.depth == 0 => *def = path_res.base_def,
|
||||||
PathResult::NonModule(..) => match self.resolve_path(&path, scope, None, Some(span)) {
|
PathResult::NonModule(..) => match self.resolve_path(&path, None, Some(span)) {
|
||||||
PathResult::Failed(msg, _) => {
|
PathResult::Failed(msg, _) => {
|
||||||
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
|
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
|
||||||
}
|
}
|
||||||
|
@ -1601,17 +1593,16 @@ impl<'a> Resolver<'a> {
|
||||||
prefix.segments.iter().map(|seg| seg.identifier).collect();
|
prefix.segments.iter().map(|seg| seg.identifier).collect();
|
||||||
// Resolve prefix of an import with empty braces (issue #28388)
|
// Resolve prefix of an import with empty braces (issue #28388)
|
||||||
if items.is_empty() && !prefix.segments.is_empty() {
|
if items.is_empty() && !prefix.segments.is_empty() {
|
||||||
let (scope, span) = (PathScope::Import, prefix.span);
|
let span = prefix.span;
|
||||||
// FIXME(#38012) This should be a module path, not anything in TypeNS.
|
// FIXME(#38012) This should be a module path, not anything in TypeNS.
|
||||||
let result =
|
let result = self.resolve_path(&path, Some(TypeNS), Some(span));
|
||||||
self.resolve_path(&path, scope, Some(TypeNS), Some(span));
|
|
||||||
let (def, msg) = match result {
|
let (def, msg) = match result {
|
||||||
PathResult::Module(module) => (module.def().unwrap(), None),
|
PathResult::Module(module) => (module.def().unwrap(), None),
|
||||||
PathResult::NonModule(res) if res.depth == 0 =>
|
PathResult::NonModule(res) if res.depth == 0 =>
|
||||||
(res.base_def, None),
|
(res.base_def, None),
|
||||||
PathResult::NonModule(_) => {
|
PathResult::NonModule(_) => {
|
||||||
// Resolve a module path for better errors
|
// Resolve a module path for better errors
|
||||||
match self.resolve_path(&path, scope, None, Some(span)) {
|
match self.resolve_path(&path, None, Some(span)) {
|
||||||
PathResult::Failed(msg, _) => (Def::Err, Some(msg)),
|
PathResult::Failed(msg, _) => (Def::Err, Some(msg)),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -1698,19 +1689,17 @@ impl<'a> Resolver<'a> {
|
||||||
|
|
||||||
fn resolve_trait_reference(&mut self,
|
fn resolve_trait_reference(&mut self,
|
||||||
path: &[Ident],
|
path: &[Ident],
|
||||||
global: bool,
|
|
||||||
generics: Option<&Generics>,
|
generics: Option<&Generics>,
|
||||||
span: Span)
|
span: Span)
|
||||||
-> PathResolution {
|
-> PathResolution {
|
||||||
let scope = if global { PathScope::Global } else { PathScope::Lexical };
|
let def = match self.resolve_path(path, None, Some(span)) {
|
||||||
let def = match self.resolve_path(path, scope, None, Some(span)) {
|
|
||||||
PathResult::Module(module) => Some(module.def().unwrap()),
|
PathResult::Module(module) => Some(module.def().unwrap()),
|
||||||
PathResult::NonModule(..) => return err_path_resolution(),
|
PathResult::NonModule(..) => return err_path_resolution(),
|
||||||
PathResult::Failed(msg, false) => {
|
PathResult::Failed(msg, false) => {
|
||||||
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
|
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
|
||||||
return err_path_resolution();
|
return err_path_resolution();
|
||||||
}
|
}
|
||||||
_ => match self.resolve_path(path, scope, Some(TypeNS), None) {
|
_ => match self.resolve_path(path, Some(TypeNS), None) {
|
||||||
PathResult::NonModule(path_resolution) => Some(path_resolution.base_def),
|
PathResult::NonModule(path_resolution) => Some(path_resolution.base_def),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
|
@ -1766,9 +1755,9 @@ impl<'a> Resolver<'a> {
|
||||||
let mut new_val = None;
|
let mut new_val = None;
|
||||||
let mut new_id = None;
|
let mut new_id = None;
|
||||||
if let Some(trait_ref) = opt_trait_ref {
|
if let Some(trait_ref) = opt_trait_ref {
|
||||||
let ast::Path { ref segments, span, global } = trait_ref.path;
|
let ast::Path { ref segments, span } = trait_ref.path;
|
||||||
let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
|
let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
|
||||||
let path_res = self.resolve_trait_reference(&path, global, generics, span);
|
let path_res = self.resolve_trait_reference(&path, generics, span);
|
||||||
assert!(path_res.depth == 0);
|
assert!(path_res.depth == 0);
|
||||||
self.record_def(trait_ref.ref_id, path_res);
|
self.record_def(trait_ref.ref_id, path_res);
|
||||||
if path_res.base_def != Def::Err {
|
if path_res.base_def != Def::Err {
|
||||||
|
@ -2260,9 +2249,8 @@ impl<'a> Resolver<'a> {
|
||||||
path: &Path,
|
path: &Path,
|
||||||
ns: Namespace)
|
ns: Namespace)
|
||||||
-> Option<PathResolution> {
|
-> Option<PathResolution> {
|
||||||
let ast::Path { ref segments, global, span } = *path;
|
let ast::Path { ref segments, span } = *path;
|
||||||
let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
|
let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
|
||||||
let scope = if global { PathScope::Global } else { PathScope::Lexical };
|
|
||||||
|
|
||||||
if let Some(qself) = maybe_qself {
|
if let Some(qself) = maybe_qself {
|
||||||
if qself.position == 0 {
|
if qself.position == 0 {
|
||||||
|
@ -2273,10 +2261,10 @@ impl<'a> Resolver<'a> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Make sure the trait is valid.
|
// Make sure the trait is valid.
|
||||||
self.resolve_trait_reference(&path[..qself.position], global, None, span);
|
self.resolve_trait_reference(&path[..qself.position], None, span);
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = match self.resolve_path(&path, scope, Some(ns), Some(span)) {
|
let result = match self.resolve_path(&path, Some(ns), Some(span)) {
|
||||||
PathResult::NonModule(path_res) => match path_res.base_def {
|
PathResult::NonModule(path_res) => match path_res.base_def {
|
||||||
Def::Trait(..) if maybe_qself.is_some() => return None,
|
Def::Trait(..) if maybe_qself.is_some() => return None,
|
||||||
_ => path_res,
|
_ => path_res,
|
||||||
|
@ -2297,7 +2285,7 @@ impl<'a> Resolver<'a> {
|
||||||
// Such behavior is required for backward compatibility.
|
// Such behavior is required for backward compatibility.
|
||||||
// The same fallback is used when `a` resolves to nothing.
|
// The same fallback is used when `a` resolves to nothing.
|
||||||
PathResult::Module(..) | PathResult::Failed(..)
|
PathResult::Module(..) | PathResult::Failed(..)
|
||||||
if scope == PathScope::Lexical && (ns == TypeNS || path.len() > 1) &&
|
if (ns == TypeNS || path.len() > 1) &&
|
||||||
self.primitive_type_table.primitive_types.contains_key(&path[0].name) => {
|
self.primitive_type_table.primitive_types.contains_key(&path[0].name) => {
|
||||||
PathResolution {
|
PathResolution {
|
||||||
base_def: Def::PrimTy(self.primitive_type_table.primitive_types[&path[0].name]),
|
base_def: Def::PrimTy(self.primitive_type_table.primitive_types[&path[0].name]),
|
||||||
|
@ -2317,7 +2305,7 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let unqualified_result = {
|
let unqualified_result = {
|
||||||
match self.resolve_path(&[*path.last().unwrap()], PathScope::Lexical, Some(ns), None) {
|
match self.resolve_path(&[*path.last().unwrap()], Some(ns), None) {
|
||||||
PathResult::NonModule(path_res) => path_res.base_def,
|
PathResult::NonModule(path_res) => path_res.base_def,
|
||||||
PathResult::Module(module) => module.def().unwrap(),
|
PathResult::Module(module) => module.def().unwrap(),
|
||||||
_ => return Some(result),
|
_ => return Some(result),
|
||||||
|
@ -2333,27 +2321,19 @@ impl<'a> Resolver<'a> {
|
||||||
|
|
||||||
fn resolve_path(&mut self,
|
fn resolve_path(&mut self,
|
||||||
path: &[Ident],
|
path: &[Ident],
|
||||||
scope: PathScope,
|
|
||||||
opt_ns: Option<Namespace>, // `None` indicates a module path
|
opt_ns: Option<Namespace>, // `None` indicates a module path
|
||||||
record_used: Option<Span>)
|
record_used: Option<Span>)
|
||||||
-> PathResult<'a> {
|
-> PathResult<'a> {
|
||||||
let (mut module, allow_self) = match scope {
|
let mut module = None;
|
||||||
PathScope::Lexical => (None, true),
|
let mut allow_super = true;
|
||||||
PathScope::Import => (Some(self.graph_root), true),
|
|
||||||
PathScope::Global => (Some(self.graph_root), false),
|
|
||||||
};
|
|
||||||
let mut allow_super = allow_self;
|
|
||||||
|
|
||||||
for (i, &ident) in path.iter().enumerate() {
|
for (i, &ident) in path.iter().enumerate() {
|
||||||
let is_last = i == path.len() - 1;
|
let is_last = i == path.len() - 1;
|
||||||
let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
|
let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
|
||||||
|
|
||||||
if i == 0 && allow_self && ns == TypeNS && ident.name == keywords::SelfValue.name() {
|
if i == 0 && ns == TypeNS && ident.name == keywords::SelfValue.name() {
|
||||||
module = Some(self.module_map[&self.current_module.normal_ancestor_id.unwrap()]);
|
module = Some(self.module_map[&self.current_module.normal_ancestor_id.unwrap()]);
|
||||||
continue
|
continue
|
||||||
} else if i == 0 && allow_self && ns == TypeNS && ident.name == "$crate" {
|
|
||||||
module = Some(self.resolve_crate_var(ident.ctxt));
|
|
||||||
continue
|
|
||||||
} else if allow_super && ns == TypeNS && ident.name == keywords::Super.name() {
|
} else if allow_super && ns == TypeNS && ident.name == keywords::Super.name() {
|
||||||
let current_module = if i == 0 { self.current_module } else { module.unwrap() };
|
let current_module = if i == 0 { self.current_module } else { module.unwrap() };
|
||||||
let self_module = self.module_map[¤t_module.normal_ancestor_id.unwrap()];
|
let self_module = self.module_map[¤t_module.normal_ancestor_id.unwrap()];
|
||||||
|
@ -2367,6 +2347,14 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
allow_super = false;
|
allow_super = false;
|
||||||
|
|
||||||
|
if i == 0 && ns == TypeNS && ident.name == keywords::CrateRoot.name() {
|
||||||
|
module = Some(self.graph_root);
|
||||||
|
continue
|
||||||
|
} else if i == 0 && ns == TypeNS && ident.name == "$crate" {
|
||||||
|
module = Some(self.resolve_crate_var(ident.ctxt));
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
let binding = if let Some(module) = module {
|
let binding = if let Some(module) = module {
|
||||||
self.resolve_ident_in_module(module, ident, ns, false, record_used)
|
self.resolve_ident_in_module(module, ident, ns, false, record_used)
|
||||||
} else if opt_ns == Some(MacroNS) {
|
} else if opt_ns == Some(MacroNS) {
|
||||||
|
@ -2430,7 +2418,7 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PathResult::Module(module.unwrap())
|
PathResult::Module(module.unwrap_or(self.graph_root))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve a local definition, potentially adjusting for closures.
|
// Resolve a local definition, potentially adjusting for closures.
|
||||||
|
@ -2665,10 +2653,8 @@ impl<'a> Resolver<'a> {
|
||||||
} else {
|
} else {
|
||||||
// Be helpful if the name refers to a struct
|
// Be helpful if the name refers to a struct
|
||||||
let path_name = path_names_to_string(path, 0);
|
let path_name = path_names_to_string(path, 0);
|
||||||
let ast::Path { ref segments, global, .. } = *path;
|
let path: Vec<_> = path.segments.iter().map(|seg| seg.identifier).collect();
|
||||||
let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
|
let type_res = match self.resolve_path(&path, Some(TypeNS), None) {
|
||||||
let scope = if global { PathScope::Global } else { PathScope::Lexical };
|
|
||||||
let type_res = match self.resolve_path(&path, scope, Some(TypeNS), None) {
|
|
||||||
PathResult::NonModule(type_res) => Some(type_res),
|
PathResult::NonModule(type_res) => Some(type_res),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
@ -2738,7 +2724,7 @@ impl<'a> Resolver<'a> {
|
||||||
} else {
|
} else {
|
||||||
// we display a help message if this is a module
|
// we display a help message if this is a module
|
||||||
if let PathResult::Module(module) =
|
if let PathResult::Module(module) =
|
||||||
self.resolve_path(&path, scope, None, None) {
|
self.resolve_path(&path, None, None) {
|
||||||
def = module.def().unwrap();
|
def = module.def().unwrap();
|
||||||
context = UnresolvedNameContext::PathIsMod(parent);
|
context = UnresolvedNameContext::PathIsMod(parent);
|
||||||
}
|
}
|
||||||
|
@ -2964,7 +2950,6 @@ impl<'a> Resolver<'a> {
|
||||||
segms.push(ident.into());
|
segms.push(ident.into());
|
||||||
let path = Path {
|
let path = Path {
|
||||||
span: span,
|
span: span,
|
||||||
global: false,
|
|
||||||
segments: segms,
|
segments: segms,
|
||||||
};
|
};
|
||||||
// the entity is accessible in the following cases:
|
// the entity is accessible in the following cases:
|
||||||
|
@ -3022,7 +3007,7 @@ impl<'a> Resolver<'a> {
|
||||||
|
|
||||||
let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
|
let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
|
||||||
let mut path_resolution = err_path_resolution();
|
let mut path_resolution = err_path_resolution();
|
||||||
let vis = match self.resolve_path(&path, PathScope::Import, None, Some(span)) {
|
let vis = match self.resolve_path(&path, None, Some(span)) {
|
||||||
PathResult::Module(module) => {
|
PathResult::Module(module) => {
|
||||||
path_resolution = PathResolution::new(module.def().unwrap());
|
path_resolution = PathResolution::new(module.def().unwrap());
|
||||||
ty::Visibility::Restricted(module.normal_ancestor_id.unwrap())
|
ty::Visibility::Restricted(module.normal_ancestor_id.unwrap())
|
||||||
|
@ -3190,15 +3175,14 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn names_to_string(names: &[Ident]) -> String {
|
fn names_to_string(names: &[Ident]) -> String {
|
||||||
let mut first = true;
|
|
||||||
let mut result = String::new();
|
let mut result = String::new();
|
||||||
for ident in names {
|
for (i, ident) in names.iter().enumerate() {
|
||||||
if first {
|
if i > 0 {
|
||||||
first = false
|
result.push_str("::");
|
||||||
} else {
|
}
|
||||||
result.push_str("::")
|
if ident.name != keywords::CrateRoot.name() {
|
||||||
|
result.push_str(&ident.name.as_str());
|
||||||
}
|
}
|
||||||
result.push_str(&ident.name.as_str());
|
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use {AmbiguityError, Resolver, ResolutionError, resolve_error};
|
use {AmbiguityError, Resolver, ResolutionError, resolve_error};
|
||||||
use {Module, ModuleKind, NameBinding, NameBindingKind, PathScope, PathResult};
|
use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult};
|
||||||
use Namespace::{self, MacroNS};
|
use Namespace::{self, MacroNS};
|
||||||
use build_reduced_graph::BuildReducedGraphVisitor;
|
use build_reduced_graph::BuildReducedGraphVisitor;
|
||||||
use resolve_imports::ImportResolver;
|
use resolve_imports::ImportResolver;
|
||||||
|
@ -30,6 +30,7 @@ use syntax::ext::tt::macro_rules;
|
||||||
use syntax::feature_gate::{emit_feature_err, GateIssue};
|
use syntax::feature_gate::{emit_feature_err, GateIssue};
|
||||||
use syntax::fold::Folder;
|
use syntax::fold::Folder;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
|
use syntax::symbol::keywords;
|
||||||
use syntax::util::lev_distance::find_best_match_for_name;
|
use syntax::util::lev_distance::find_best_match_for_name;
|
||||||
use syntax::visit::Visitor;
|
use syntax::visit::Visitor;
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
|
@ -105,15 +106,13 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||||
fn fold_path(&mut self, mut path: ast::Path) -> ast::Path {
|
fn fold_path(&mut self, mut path: ast::Path) -> ast::Path {
|
||||||
let ident = path.segments[0].identifier;
|
let ident = path.segments[0].identifier;
|
||||||
if ident.name == "$crate" {
|
if ident.name == "$crate" {
|
||||||
path.global = true;
|
path.segments[0].identifier.name = keywords::CrateRoot.name();
|
||||||
let module = self.0.resolve_crate_var(ident.ctxt);
|
let module = self.0.resolve_crate_var(ident.ctxt);
|
||||||
if module.is_local() {
|
if !module.is_local() {
|
||||||
path.segments.remove(0);
|
path.segments.insert(1, match module.kind {
|
||||||
} else {
|
ModuleKind::Def(_, name) => ast::Ident::with_empty_ctxt(name).into(),
|
||||||
path.segments[0].identifier = match module.kind {
|
|
||||||
ModuleKind::Def(_, name) => ast::Ident::with_empty_ctxt(name),
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
path
|
path
|
||||||
|
@ -182,7 +181,7 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||||
|
|
||||||
fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, force: bool)
|
fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, force: bool)
|
||||||
-> Result<Rc<SyntaxExtension>, Determinacy> {
|
-> Result<Rc<SyntaxExtension>, Determinacy> {
|
||||||
let ast::Path { ref segments, global, span } = *path;
|
let ast::Path { ref segments, span } = *path;
|
||||||
if segments.iter().any(|segment| segment.parameters.is_some()) {
|
if segments.iter().any(|segment| segment.parameters.is_some()) {
|
||||||
let kind =
|
let kind =
|
||||||
if segments.last().unwrap().parameters.is_some() { "macro" } else { "module" };
|
if segments.last().unwrap().parameters.is_some() { "macro" } else { "module" };
|
||||||
|
@ -191,12 +190,11 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||||
return Err(Determinacy::Determined);
|
return Err(Determinacy::Determined);
|
||||||
}
|
}
|
||||||
|
|
||||||
let path_scope = if global { PathScope::Global } else { PathScope::Lexical };
|
|
||||||
let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
|
let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
|
||||||
let invocation = self.invocations[&scope];
|
let invocation = self.invocations[&scope];
|
||||||
self.current_module = invocation.module.get();
|
self.current_module = invocation.module.get();
|
||||||
|
|
||||||
if path.len() > 1 || global {
|
if path.len() > 1 {
|
||||||
if !self.use_extern_macros {
|
if !self.use_extern_macros {
|
||||||
let msg = "non-ident macro paths are experimental";
|
let msg = "non-ident macro paths are experimental";
|
||||||
let feature = "use_extern_macros";
|
let feature = "use_extern_macros";
|
||||||
|
@ -204,7 +202,7 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||||
return Err(Determinacy::Determined);
|
return Err(Determinacy::Determined);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ext = match self.resolve_path(&path, path_scope, Some(MacroNS), None) {
|
let ext = match self.resolve_path(&path, Some(MacroNS), None) {
|
||||||
PathResult::NonModule(path_res) => match path_res.base_def {
|
PathResult::NonModule(path_res) => match path_res.base_def {
|
||||||
Def::Err => Err(Determinacy::Determined),
|
Def::Err => Err(Determinacy::Determined),
|
||||||
def @ _ => Ok(self.get_macro(def)),
|
def @ _ => Ok(self.get_macro(def)),
|
||||||
|
@ -214,7 +212,7 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||||
_ => Err(Determinacy::Determined),
|
_ => Err(Determinacy::Determined),
|
||||||
};
|
};
|
||||||
self.current_module.macro_resolutions.borrow_mut()
|
self.current_module.macro_resolutions.borrow_mut()
|
||||||
.push((path.into_boxed_slice(), path_scope, span));
|
.push((path.into_boxed_slice(), span));
|
||||||
return ext;
|
return ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,8 +349,8 @@ impl<'a> Resolver<'a> {
|
||||||
|
|
||||||
pub fn finalize_current_module_macro_resolutions(&mut self) {
|
pub fn finalize_current_module_macro_resolutions(&mut self) {
|
||||||
let module = self.current_module;
|
let module = self.current_module;
|
||||||
for &(ref path, scope, span) in module.macro_resolutions.borrow().iter() {
|
for &(ref path, span) in module.macro_resolutions.borrow().iter() {
|
||||||
match self.resolve_path(path, scope, Some(MacroNS), Some(span)) {
|
match self.resolve_path(path, Some(MacroNS), Some(span)) {
|
||||||
PathResult::NonModule(_) => {},
|
PathResult::NonModule(_) => {},
|
||||||
PathResult::Failed(msg, _) => {
|
PathResult::Failed(msg, _) => {
|
||||||
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
|
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
|
||||||
|
|
|
@ -12,7 +12,7 @@ use self::ImportDirectiveSubclass::*;
|
||||||
|
|
||||||
use {AmbiguityError, Module, PerNS};
|
use {AmbiguityError, Module, PerNS};
|
||||||
use Namespace::{self, TypeNS, MacroNS};
|
use Namespace::{self, TypeNS, MacroNS};
|
||||||
use {NameBinding, NameBindingKind, PathResult, PathScope, PrivacyError};
|
use {NameBinding, NameBindingKind, PathResult, PrivacyError};
|
||||||
use Resolver;
|
use Resolver;
|
||||||
use {names_to_string, module_to_string};
|
use {names_to_string, module_to_string};
|
||||||
use {resolve_error, ResolutionError};
|
use {resolve_error, ResolutionError};
|
||||||
|
@ -24,6 +24,7 @@ use rustc::hir::def::*;
|
||||||
use syntax::ast::{Ident, NodeId};
|
use syntax::ast::{Ident, NodeId};
|
||||||
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
|
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
|
||||||
use syntax::ext::hygiene::Mark;
|
use syntax::ext::hygiene::Mark;
|
||||||
|
use syntax::parse::token;
|
||||||
use syntax::symbol::keywords;
|
use syntax::symbol::keywords;
|
||||||
use syntax::util::lev_distance::find_best_match_for_name;
|
use syntax::util::lev_distance::find_best_match_for_name;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
@ -490,7 +491,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||||
// For better failure detection, pretend that the import will not define any names
|
// For better failure detection, pretend that the import will not define any names
|
||||||
// while resolving its module path.
|
// while resolving its module path.
|
||||||
directive.vis.set(ty::Visibility::PrivateExternal);
|
directive.vis.set(ty::Visibility::PrivateExternal);
|
||||||
let result = self.resolve_path(&directive.module_path, PathScope::Import, None, None);
|
let result = self.resolve_path(&directive.module_path, None, None);
|
||||||
directive.vis.set(vis);
|
directive.vis.set(vis);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
|
@ -553,15 +554,17 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||||
self.current_module = directive.parent;
|
self.current_module = directive.parent;
|
||||||
|
|
||||||
let ImportDirective { ref module_path, span, .. } = *directive;
|
let ImportDirective { ref module_path, span, .. } = *directive;
|
||||||
let module_result = self.resolve_path(&module_path, PathScope::Import, None, Some(span));
|
let module_result = self.resolve_path(&module_path, None, Some(span));
|
||||||
let module = match module_result {
|
let module = match module_result {
|
||||||
PathResult::Module(module) => module,
|
PathResult::Module(module) => module,
|
||||||
PathResult::Failed(msg, _) => {
|
PathResult::Failed(msg, _) => {
|
||||||
let mut path = vec![keywords::SelfValue.ident()];
|
let (mut self_path, mut self_result) = (module_path.clone(), None);
|
||||||
path.extend(module_path);
|
if !self_path.is_empty() && !token::Ident(self_path[0]).is_path_segment_keyword() {
|
||||||
let result = self.resolve_path(&path, PathScope::Import, None, None);
|
self_path[0].name = keywords::SelfValue.name();
|
||||||
return if let PathResult::Module(..) = result {
|
self_result = Some(self.resolve_path(&self_path, None, None));
|
||||||
Some(format!("Did you mean `self::{}`?", &names_to_string(module_path)))
|
}
|
||||||
|
return if let Some(PathResult::Module(..)) = self_result {
|
||||||
|
Some(format!("Did you mean `{}`?", names_to_string(&self_path)))
|
||||||
} else {
|
} else {
|
||||||
Some(msg)
|
Some(msg)
|
||||||
};
|
};
|
||||||
|
@ -787,6 +790,8 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_path_to_string(names: &[Ident], subclass: &ImportDirectiveSubclass) -> String {
|
fn import_path_to_string(names: &[Ident], subclass: &ImportDirectiveSubclass) -> String {
|
||||||
|
let global = !names.is_empty() && names[0].name == keywords::CrateRoot.name();
|
||||||
|
let names = if global { &names[1..] } else { names };
|
||||||
if names.is_empty() {
|
if names.is_empty() {
|
||||||
import_directive_subclass_to_string(subclass)
|
import_directive_subclass_to_string(subclass)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -143,19 +143,20 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
// a str representation of the entire prefix.
|
// a str representation of the entire prefix.
|
||||||
fn process_path_prefixes(&self, path: &ast::Path) -> Vec<(Span, String)> {
|
fn process_path_prefixes(&self, path: &ast::Path) -> Vec<(Span, String)> {
|
||||||
let spans = self.span.spans_for_path_segments(path);
|
let spans = self.span.spans_for_path_segments(path);
|
||||||
|
let segments = &path.segments[if path.is_global() { 1 } else { 0 }..];
|
||||||
|
|
||||||
// Paths to enums seem to not match their spans - the span includes all the
|
// Paths to enums seem to not match their spans - the span includes all the
|
||||||
// variants too. But they seem to always be at the end, so I hope we can cope with
|
// variants too. But they seem to always be at the end, so I hope we can cope with
|
||||||
// always using the first ones. So, only error out if we don't have enough spans.
|
// always using the first ones. So, only error out if we don't have enough spans.
|
||||||
// What could go wrong...?
|
// What could go wrong...?
|
||||||
if spans.len() < path.segments.len() {
|
if spans.len() < segments.len() {
|
||||||
if generated_code(path.span) {
|
if generated_code(path.span) {
|
||||||
return vec![];
|
return vec![];
|
||||||
}
|
}
|
||||||
error!("Mis-calculated spans for path '{}'. Found {} spans, expected {}. Found spans:",
|
error!("Mis-calculated spans for path '{}'. Found {} spans, expected {}. Found spans:",
|
||||||
path_to_string(path),
|
path_to_string(path),
|
||||||
spans.len(),
|
spans.len(),
|
||||||
path.segments.len());
|
segments.len());
|
||||||
for s in &spans {
|
for s in &spans {
|
||||||
let loc = self.sess.codemap().lookup_char_pos(s.lo);
|
let loc = self.sess.codemap().lookup_char_pos(s.lo);
|
||||||
error!(" '{}' in {}, line {}",
|
error!(" '{}' in {}, line {}",
|
||||||
|
@ -170,14 +171,13 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
let mut result: Vec<(Span, String)> = vec![];
|
let mut result: Vec<(Span, String)> = vec![];
|
||||||
|
|
||||||
let mut segs = vec![];
|
let mut segs = vec![];
|
||||||
for (i, (seg, span)) in path.segments.iter().zip(&spans).enumerate() {
|
for (i, (seg, span)) in segments.iter().zip(&spans).enumerate() {
|
||||||
segs.push(seg.clone());
|
segs.push(seg.clone());
|
||||||
let sub_path = ast::Path {
|
let sub_path = ast::Path {
|
||||||
span: *span, // span for the last segment
|
span: *span, // span for the last segment
|
||||||
global: path.global,
|
|
||||||
segments: segs,
|
segments: segs,
|
||||||
};
|
};
|
||||||
let qualname = if i == 0 && path.global {
|
let qualname = if i == 0 && path.is_global() {
|
||||||
format!("::{}", path_to_string(&sub_path))
|
format!("::{}", path_to_string(&sub_path))
|
||||||
} else {
|
} else {
|
||||||
path_to_string(&sub_path)
|
path_to_string(&sub_path)
|
||||||
|
@ -189,20 +189,11 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
// The global arg allows us to override the global-ness of the path (which
|
fn write_sub_paths(&mut self, path: &ast::Path) {
|
||||||
// actually means 'does the path start with `::`', rather than 'is the path
|
|
||||||
// semantically global). We use the override for `use` imports (etc.) where
|
|
||||||
// the syntax is non-global, but the semantics are global.
|
|
||||||
fn write_sub_paths(&mut self, path: &ast::Path, global: bool) {
|
|
||||||
let sub_paths = self.process_path_prefixes(path);
|
let sub_paths = self.process_path_prefixes(path);
|
||||||
for (i, &(ref span, ref qualname)) in sub_paths.iter().enumerate() {
|
for (span, qualname) in sub_paths {
|
||||||
let qualname = if i == 0 && global && !path.global {
|
|
||||||
format!("::{}", qualname)
|
|
||||||
} else {
|
|
||||||
qualname.clone()
|
|
||||||
};
|
|
||||||
self.dumper.mod_ref(ModRefData {
|
self.dumper.mod_ref(ModRefData {
|
||||||
span: *span,
|
span: span,
|
||||||
qualname: qualname,
|
qualname: qualname,
|
||||||
scope: self.cur_scope,
|
scope: self.cur_scope,
|
||||||
ref_id: None
|
ref_id: None
|
||||||
|
@ -212,22 +203,16 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
|
|
||||||
// As write_sub_paths, but does not process the last ident in the path (assuming it
|
// As write_sub_paths, but does not process the last ident in the path (assuming it
|
||||||
// will be processed elsewhere). See note on write_sub_paths about global.
|
// will be processed elsewhere). See note on write_sub_paths about global.
|
||||||
fn write_sub_paths_truncated(&mut self, path: &ast::Path, global: bool) {
|
fn write_sub_paths_truncated(&mut self, path: &ast::Path) {
|
||||||
let sub_paths = self.process_path_prefixes(path);
|
let sub_paths = self.process_path_prefixes(path);
|
||||||
let len = sub_paths.len();
|
let len = sub_paths.len();
|
||||||
if len <= 1 {
|
if len <= 1 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sub_paths = &sub_paths[..len-1];
|
for (span, qualname) in sub_paths.into_iter().take(len - 1) {
|
||||||
for (i, &(ref span, ref qualname)) in sub_paths.iter().enumerate() {
|
|
||||||
let qualname = if i == 0 && global && !path.global {
|
|
||||||
format!("::{}", qualname)
|
|
||||||
} else {
|
|
||||||
qualname.clone()
|
|
||||||
};
|
|
||||||
self.dumper.mod_ref(ModRefData {
|
self.dumper.mod_ref(ModRefData {
|
||||||
span: *span,
|
span: span,
|
||||||
qualname: qualname,
|
qualname: qualname,
|
||||||
scope: self.cur_scope,
|
scope: self.cur_scope,
|
||||||
ref_id: None
|
ref_id: None
|
||||||
|
@ -935,7 +920,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
Def::Union(..) |
|
Def::Union(..) |
|
||||||
Def::Variant(..) |
|
Def::Variant(..) |
|
||||||
Def::TyAlias(..) |
|
Def::TyAlias(..) |
|
||||||
Def::AssociatedTy(..) => self.write_sub_paths_truncated(path, false),
|
Def::AssociatedTy(..) => self.write_sub_paths_truncated(path),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -946,7 +931,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
fields: &'l [ast::Field],
|
fields: &'l [ast::Field],
|
||||||
variant: &'l ty::VariantDef,
|
variant: &'l ty::VariantDef,
|
||||||
base: &'l Option<P<ast::Expr>>) {
|
base: &'l Option<P<ast::Expr>>) {
|
||||||
self.write_sub_paths_truncated(path, false);
|
self.write_sub_paths_truncated(path);
|
||||||
|
|
||||||
if let Some(struct_lit_data) = self.save_ctxt.get_expr_data(ex) {
|
if let Some(struct_lit_data) = self.save_ctxt.get_expr_data(ex) {
|
||||||
down_cast_data!(struct_lit_data, TypeRefData, ex.span);
|
down_cast_data!(struct_lit_data, TypeRefData, ex.span);
|
||||||
|
@ -1201,7 +1186,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll,
|
||||||
visibility: From::from(&item.vis),
|
visibility: From::from(&item.vis),
|
||||||
}.lower(self.tcx));
|
}.lower(self.tcx));
|
||||||
}
|
}
|
||||||
self.write_sub_paths_truncated(path, true);
|
self.write_sub_paths_truncated(path);
|
||||||
}
|
}
|
||||||
ast::ViewPathGlob(ref path) => {
|
ast::ViewPathGlob(ref path) => {
|
||||||
// Make a comma-separated list of names of imported modules.
|
// Make a comma-separated list of names of imported modules.
|
||||||
|
@ -1225,7 +1210,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll,
|
||||||
visibility: From::from(&item.vis),
|
visibility: From::from(&item.vis),
|
||||||
}.lower(self.tcx));
|
}.lower(self.tcx));
|
||||||
}
|
}
|
||||||
self.write_sub_paths(path, true);
|
self.write_sub_paths(path);
|
||||||
}
|
}
|
||||||
ast::ViewPathList(ref path, ref list) => {
|
ast::ViewPathList(ref path, ref list) => {
|
||||||
for plid in list {
|
for plid in list {
|
||||||
|
@ -1237,7 +1222,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.write_sub_paths(path, true);
|
self.write_sub_paths(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1340,7 +1325,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll,
|
||||||
}.lower(self.tcx));
|
}.lower(self.tcx));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.write_sub_paths_truncated(path, false);
|
self.write_sub_paths_truncated(path);
|
||||||
|
|
||||||
visit::walk_path(self, path);
|
visit::walk_path(self, path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1737,7 +1737,6 @@ impl Clean<Type> for hir::Ty {
|
||||||
segments.pop();
|
segments.pop();
|
||||||
let trait_path = hir::Path {
|
let trait_path = hir::Path {
|
||||||
span: p.span,
|
span: p.span,
|
||||||
global: p.global,
|
|
||||||
def: Def::Trait(cx.tcx.associated_item(p.def.def_id()).container.id()),
|
def: Def::Trait(cx.tcx.associated_item(p.def.def_id()).container.id()),
|
||||||
segments: segments.into(),
|
segments: segments.into(),
|
||||||
};
|
};
|
||||||
|
@ -1756,7 +1755,6 @@ impl Clean<Type> for hir::Ty {
|
||||||
}
|
}
|
||||||
let trait_path = hir::Path {
|
let trait_path = hir::Path {
|
||||||
span: self.span,
|
span: self.span,
|
||||||
global: false,
|
|
||||||
def: def,
|
def: def,
|
||||||
segments: vec![].into(),
|
segments: vec![].into(),
|
||||||
};
|
};
|
||||||
|
@ -2213,9 +2211,9 @@ impl Path {
|
||||||
impl Clean<Path> for hir::Path {
|
impl Clean<Path> for hir::Path {
|
||||||
fn clean(&self, cx: &DocContext) -> Path {
|
fn clean(&self, cx: &DocContext) -> Path {
|
||||||
Path {
|
Path {
|
||||||
global: self.global,
|
global: self.is_global(),
|
||||||
def: self.def,
|
def: self.def,
|
||||||
segments: self.segments.clean(cx),
|
segments: if self.is_global() { &self.segments[1..] } else { &self.segments }.clean(cx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2270,24 +2268,19 @@ impl Clean<PathSegment> for hir::PathSegment {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn qpath_to_string(p: &hir::QPath) -> String {
|
fn qpath_to_string(p: &hir::QPath) -> String {
|
||||||
let (segments, global) = match *p {
|
let segments = match *p {
|
||||||
hir::QPath::Resolved(_, ref path) => {
|
hir::QPath::Resolved(_, ref path) => &path.segments,
|
||||||
(&path.segments, path.global)
|
hir::QPath::TypeRelative(_, ref segment) => return segment.name.to_string(),
|
||||||
}
|
|
||||||
hir::QPath::TypeRelative(_, ref segment) => {
|
|
||||||
return segment.name.to_string()
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
let mut first = true;
|
for (i, seg) in segments.iter().enumerate() {
|
||||||
for i in segments.iter().map(|x| x.name.as_str()) {
|
if i > 0 {
|
||||||
if !first || global {
|
|
||||||
s.push_str("::");
|
s.push_str("::");
|
||||||
} else {
|
|
||||||
first = false;
|
|
||||||
}
|
}
|
||||||
s.push_str(&i);
|
if seg.name != keywords::CrateRoot.name() {
|
||||||
|
s.push_str(&*seg.name.as_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,10 +111,8 @@ pub struct LifetimeDef {
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
||||||
pub struct Path {
|
pub struct Path {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
/// A `::foo` path, is relative to the crate root rather than current
|
|
||||||
/// module (like paths in an import).
|
|
||||||
pub global: bool,
|
|
||||||
/// The segments in the path: the things separated by `::`.
|
/// The segments in the path: the things separated by `::`.
|
||||||
|
/// Global paths begin with `keywords::CrateRoot`.
|
||||||
pub segments: Vec<PathSegment>,
|
pub segments: Vec<PathSegment>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,10 +134,22 @@ impl Path {
|
||||||
pub fn from_ident(s: Span, identifier: Ident) -> Path {
|
pub fn from_ident(s: Span, identifier: Ident) -> Path {
|
||||||
Path {
|
Path {
|
||||||
span: s,
|
span: s,
|
||||||
global: false,
|
|
||||||
segments: vec![identifier.into()],
|
segments: vec![identifier.into()],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn default_to_global(mut self) -> Path {
|
||||||
|
let name = self.segments[0].identifier.name;
|
||||||
|
if !self.is_global() && name != "$crate" &&
|
||||||
|
name != keywords::SelfValue.name() && name != keywords::Super.name() {
|
||||||
|
self.segments.insert(0, PathSegment::crate_root());
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_global(&self) -> bool {
|
||||||
|
!self.segments.is_empty() && self.segments[0].identifier.name == keywords::CrateRoot.name()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A segment of a path: an identifier, an optional lifetime, and a set of types.
|
/// A segment of a path: an identifier, an optional lifetime, and a set of types.
|
||||||
|
@ -166,6 +176,15 @@ impl From<Ident> for PathSegment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PathSegment {
|
||||||
|
pub fn crate_root() -> Self {
|
||||||
|
PathSegment {
|
||||||
|
identifier: keywords::CrateRoot.ident(),
|
||||||
|
parameters: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Parameters of a path segment.
|
/// Parameters of a path segment.
|
||||||
///
|
///
|
||||||
/// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
|
/// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
|
||||||
|
|
|
@ -322,7 +322,12 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
bindings: Vec<ast::TypeBinding> )
|
bindings: Vec<ast::TypeBinding> )
|
||||||
-> ast::Path {
|
-> ast::Path {
|
||||||
let last_identifier = idents.pop().unwrap();
|
let last_identifier = idents.pop().unwrap();
|
||||||
let mut segments: Vec<ast::PathSegment> = idents.into_iter().map(Into::into).collect();
|
let mut segments: Vec<ast::PathSegment> = Vec::new();
|
||||||
|
if global {
|
||||||
|
segments.push(ast::PathSegment::crate_root());
|
||||||
|
}
|
||||||
|
|
||||||
|
segments.extend(idents.into_iter().map(Into::into));
|
||||||
let parameters = if lifetimes.is_empty() && types.is_empty() && bindings.is_empty() {
|
let parameters = if lifetimes.is_empty() && types.is_empty() && bindings.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -335,7 +340,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
segments.push(ast::PathSegment { identifier: last_identifier, parameters: parameters });
|
segments.push(ast::PathSegment { identifier: last_identifier, parameters: parameters });
|
||||||
ast::Path {
|
ast::Path {
|
||||||
span: sp,
|
span: sp,
|
||||||
global: global,
|
|
||||||
segments: segments,
|
segments: segments,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ use std::mem;
|
||||||
pub fn placeholder(kind: ExpansionKind, id: ast::NodeId) -> Expansion {
|
pub fn placeholder(kind: ExpansionKind, id: ast::NodeId) -> Expansion {
|
||||||
fn mac_placeholder() -> ast::Mac {
|
fn mac_placeholder() -> ast::Mac {
|
||||||
dummy_spanned(ast::Mac_ {
|
dummy_spanned(ast::Mac_ {
|
||||||
path: ast::Path { span: DUMMY_SP, global: false, segments: Vec::new() },
|
path: ast::Path { span: DUMMY_SP, segments: Vec::new() },
|
||||||
tts: Vec::new(),
|
tts: Vec::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -433,9 +433,8 @@ pub fn noop_fold_usize<T: Folder>(i: usize, _: &mut T) -> usize {
|
||||||
i
|
i
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn noop_fold_path<T: Folder>(Path {global, segments, span}: Path, fld: &mut T) -> Path {
|
pub fn noop_fold_path<T: Folder>(Path { segments, span }: Path, fld: &mut T) -> Path {
|
||||||
Path {
|
Path {
|
||||||
global: global,
|
|
||||||
segments: segments.move_map(|PathSegment {identifier, parameters}| PathSegment {
|
segments: segments.move_map(|PathSegment {identifier, parameters}| PathSegment {
|
||||||
identifier: fld.fold_ident(identifier),
|
identifier: fld.fold_ident(identifier),
|
||||||
parameters: parameters.map(|ps| ps.map(|ps| fld.fold_path_parameters(ps))),
|
parameters: parameters.map(|ps| ps.map(|ps| fld.fold_path_parameters(ps))),
|
||||||
|
|
|
@ -633,7 +633,6 @@ mod tests {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::ExprKind::Path(None, ast::Path {
|
node: ast::ExprKind::Path(None, ast::Path {
|
||||||
span: sp(0, 1),
|
span: sp(0, 1),
|
||||||
global: false,
|
|
||||||
segments: vec![Ident::from_str("a").into()],
|
segments: vec![Ident::from_str("a").into()],
|
||||||
}),
|
}),
|
||||||
span: sp(0, 1),
|
span: sp(0, 1),
|
||||||
|
@ -647,8 +646,9 @@ mod tests {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::ExprKind::Path(None, ast::Path {
|
node: ast::ExprKind::Path(None, ast::Path {
|
||||||
span: sp(0, 6),
|
span: sp(0, 6),
|
||||||
global: true,
|
segments: vec![ast::PathSegment::crate_root(),
|
||||||
segments: vec![Ident::from_str("a").into(), Ident::from_str("b").into()],
|
Ident::from_str("a").into(),
|
||||||
|
Ident::from_str("b").into()]
|
||||||
}),
|
}),
|
||||||
span: sp(0, 6),
|
span: sp(0, 6),
|
||||||
attrs: ThinVec::new(),
|
attrs: ThinVec::new(),
|
||||||
|
@ -757,7 +757,6 @@ mod tests {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node:ast::ExprKind::Path(None, ast::Path{
|
node:ast::ExprKind::Path(None, ast::Path{
|
||||||
span: sp(7, 8),
|
span: sp(7, 8),
|
||||||
global: false,
|
|
||||||
segments: vec![Ident::from_str("d").into()],
|
segments: vec![Ident::from_str("d").into()],
|
||||||
}),
|
}),
|
||||||
span:sp(7,8),
|
span:sp(7,8),
|
||||||
|
@ -775,7 +774,6 @@ mod tests {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::ExprKind::Path(None, ast::Path {
|
node: ast::ExprKind::Path(None, ast::Path {
|
||||||
span:sp(0,1),
|
span:sp(0,1),
|
||||||
global:false,
|
|
||||||
segments: vec![Ident::from_str("b").into()],
|
segments: vec![Ident::from_str("b").into()],
|
||||||
}),
|
}),
|
||||||
span: sp(0,1),
|
span: sp(0,1),
|
||||||
|
@ -817,7 +815,6 @@ mod tests {
|
||||||
ty: P(ast::Ty{id: ast::DUMMY_NODE_ID,
|
ty: P(ast::Ty{id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::TyKind::Path(None, ast::Path{
|
node: ast::TyKind::Path(None, ast::Path{
|
||||||
span:sp(10,13),
|
span:sp(10,13),
|
||||||
global:false,
|
|
||||||
segments: vec![Ident::from_str("i32").into()],
|
segments: vec![Ident::from_str("i32").into()],
|
||||||
}),
|
}),
|
||||||
span:sp(10,13)
|
span:sp(10,13)
|
||||||
|
@ -860,7 +857,6 @@ mod tests {
|
||||||
node: ast::ExprKind::Path(None,
|
node: ast::ExprKind::Path(None,
|
||||||
ast::Path{
|
ast::Path{
|
||||||
span:sp(17,18),
|
span:sp(17,18),
|
||||||
global:false,
|
|
||||||
segments: vec![Ident::from_str("b").into()],
|
segments: vec![Ident::from_str("b").into()],
|
||||||
}),
|
}),
|
||||||
span: sp(17,18),
|
span: sp(17,18),
|
||||||
|
|
|
@ -1614,7 +1614,6 @@ impl<'a> Parser<'a> {
|
||||||
} else {
|
} else {
|
||||||
ast::Path {
|
ast::Path {
|
||||||
span: span,
|
span: span,
|
||||||
global: false,
|
|
||||||
segments: vec![]
|
segments: vec![]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1658,7 +1657,7 @@ impl<'a> Parser<'a> {
|
||||||
// Parse any number of segments and bound sets. A segment is an
|
// Parse any number of segments and bound sets. A segment is an
|
||||||
// identifier followed by an optional lifetime and a set of types.
|
// identifier followed by an optional lifetime and a set of types.
|
||||||
// A bound set is a set of type parameter bounds.
|
// A bound set is a set of type parameter bounds.
|
||||||
let segments = match mode {
|
let mut segments = match mode {
|
||||||
PathStyle::Type => {
|
PathStyle::Type => {
|
||||||
self.parse_path_segments_without_colons()?
|
self.parse_path_segments_without_colons()?
|
||||||
}
|
}
|
||||||
|
@ -1670,13 +1669,16 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if is_global {
|
||||||
|
segments.insert(0, ast::PathSegment::crate_root());
|
||||||
|
}
|
||||||
|
|
||||||
// Assemble the span.
|
// Assemble the span.
|
||||||
let span = mk_sp(lo, self.prev_span.hi);
|
let span = mk_sp(lo, self.prev_span.hi);
|
||||||
|
|
||||||
// Assemble the result.
|
// Assemble the result.
|
||||||
Ok(ast::Path {
|
Ok(ast::Path {
|
||||||
span: span,
|
span: span,
|
||||||
global: is_global,
|
|
||||||
segments: segments,
|
segments: segments,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -5180,7 +5182,7 @@ impl<'a> Parser<'a> {
|
||||||
} else if self.eat_keyword(keywords::Crate) {
|
} else if self.eat_keyword(keywords::Crate) {
|
||||||
pub_crate(self)
|
pub_crate(self)
|
||||||
} else {
|
} else {
|
||||||
let path = self.parse_path(PathStyle::Mod)?;
|
let path = self.parse_path(PathStyle::Mod)?.default_to_global();
|
||||||
self.expect(&token::CloseDelim(token::Paren))?;
|
self.expect(&token::CloseDelim(token::Paren))?;
|
||||||
Ok(Visibility::Restricted { path: P(path), id: ast::DUMMY_NODE_ID })
|
Ok(Visibility::Restricted { path: P(path), id: ast::DUMMY_NODE_ID })
|
||||||
}
|
}
|
||||||
|
@ -6068,9 +6070,9 @@ impl<'a> Parser<'a> {
|
||||||
if self.check(&token::OpenDelim(token::Brace)) || self.check(&token::BinOp(token::Star)) ||
|
if self.check(&token::OpenDelim(token::Brace)) || self.check(&token::BinOp(token::Star)) ||
|
||||||
self.is_import_coupler() {
|
self.is_import_coupler() {
|
||||||
// `{foo, bar}`, `::{foo, bar}`, `*`, or `::*`.
|
// `{foo, bar}`, `::{foo, bar}`, `*`, or `::*`.
|
||||||
|
self.eat(&token::ModSep);
|
||||||
let prefix = ast::Path {
|
let prefix = ast::Path {
|
||||||
global: self.eat(&token::ModSep),
|
segments: vec![ast::PathSegment::crate_root()],
|
||||||
segments: Vec::new(),
|
|
||||||
span: mk_sp(lo, self.span.hi),
|
span: mk_sp(lo, self.span.hi),
|
||||||
};
|
};
|
||||||
let view_path_kind = if self.eat(&token::BinOp(token::Star)) {
|
let view_path_kind = if self.eat(&token::BinOp(token::Star)) {
|
||||||
|
@ -6080,7 +6082,7 @@ impl<'a> Parser<'a> {
|
||||||
};
|
};
|
||||||
Ok(P(spanned(lo, self.span.hi, view_path_kind)))
|
Ok(P(spanned(lo, self.span.hi, view_path_kind)))
|
||||||
} else {
|
} else {
|
||||||
let prefix = self.parse_path(PathStyle::Mod)?;
|
let prefix = self.parse_path(PathStyle::Mod)?.default_to_global();
|
||||||
if self.is_import_coupler() {
|
if self.is_import_coupler() {
|
||||||
// `foo::bar::{a, b}` or `foo::bar::*`
|
// `foo::bar::{a, b}` or `foo::bar::*`
|
||||||
self.bump();
|
self.bump();
|
||||||
|
|
|
@ -371,7 +371,7 @@ pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn path_to_string(p: &ast::Path) -> String {
|
pub fn path_to_string(p: &ast::Path) -> String {
|
||||||
to_string(|s| s.print_path(p, false, 0))
|
to_string(|s| s.print_path(p, false, 0, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ident_to_string(id: ast::Ident) -> String {
|
pub fn ident_to_string(id: ast::Ident) -> String {
|
||||||
|
@ -435,7 +435,8 @@ pub fn visibility_qualified(vis: &ast::Visibility, s: &str) -> String {
|
||||||
match *vis {
|
match *vis {
|
||||||
ast::Visibility::Public => format!("pub {}", s),
|
ast::Visibility::Public => format!("pub {}", s),
|
||||||
ast::Visibility::Crate(_) => format!("pub(crate) {}", s),
|
ast::Visibility::Crate(_) => format!("pub(crate) {}", s),
|
||||||
ast::Visibility::Restricted { ref path, .. } => format!("pub({}) {}", path, s),
|
ast::Visibility::Restricted { ref path, .. } =>
|
||||||
|
format!("pub({}) {}", to_string(|s| s.print_path(path, false, 0, true)), s),
|
||||||
ast::Visibility::Inherited => s.to_string()
|
ast::Visibility::Inherited => s.to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1021,7 +1022,7 @@ impl<'a> State<'a> {
|
||||||
&generics));
|
&generics));
|
||||||
}
|
}
|
||||||
ast::TyKind::Path(None, ref path) => {
|
ast::TyKind::Path(None, ref path) => {
|
||||||
try!(self.print_path(path, false, 0));
|
try!(self.print_path(path, false, 0, false));
|
||||||
}
|
}
|
||||||
ast::TyKind::Path(Some(ref qself), ref path) => {
|
ast::TyKind::Path(Some(ref qself), ref path) => {
|
||||||
try!(self.print_qpath(path, qself, false))
|
try!(self.print_qpath(path, qself, false))
|
||||||
|
@ -1332,7 +1333,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
ast::ItemKind::Mac(codemap::Spanned { ref node, .. }) => {
|
ast::ItemKind::Mac(codemap::Spanned { ref node, .. }) => {
|
||||||
try!(self.print_visibility(&item.vis));
|
try!(self.print_visibility(&item.vis));
|
||||||
try!(self.print_path(&node.path, false, 0));
|
try!(self.print_path(&node.path, false, 0, false));
|
||||||
try!(word(&mut self.s, "! "));
|
try!(word(&mut self.s, "! "));
|
||||||
try!(self.print_ident(item.ident));
|
try!(self.print_ident(item.ident));
|
||||||
try!(self.cbox(INDENT_UNIT));
|
try!(self.cbox(INDENT_UNIT));
|
||||||
|
@ -1347,7 +1348,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_trait_ref(&mut self, t: &ast::TraitRef) -> io::Result<()> {
|
fn print_trait_ref(&mut self, t: &ast::TraitRef) -> io::Result<()> {
|
||||||
self.print_path(&t.path, false, 0)
|
self.print_path(&t.path, false, 0, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> io::Result<()> {
|
fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> io::Result<()> {
|
||||||
|
@ -1405,8 +1406,10 @@ impl<'a> State<'a> {
|
||||||
match *vis {
|
match *vis {
|
||||||
ast::Visibility::Public => self.word_nbsp("pub"),
|
ast::Visibility::Public => self.word_nbsp("pub"),
|
||||||
ast::Visibility::Crate(_) => self.word_nbsp("pub(crate)"),
|
ast::Visibility::Crate(_) => self.word_nbsp("pub(crate)"),
|
||||||
ast::Visibility::Restricted { ref path, .. } =>
|
ast::Visibility::Restricted { ref path, .. } => {
|
||||||
self.word_nbsp(&format!("pub({})", path)),
|
let path = to_string(|s| s.print_path(path, false, 0, true));
|
||||||
|
self.word_nbsp(&format!("pub({})", path))
|
||||||
|
}
|
||||||
ast::Visibility::Inherited => Ok(())
|
ast::Visibility::Inherited => Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1571,7 +1574,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
ast::TraitItemKind::Macro(codemap::Spanned { ref node, .. }) => {
|
ast::TraitItemKind::Macro(codemap::Spanned { ref node, .. }) => {
|
||||||
// code copied from ItemKind::Mac:
|
// code copied from ItemKind::Mac:
|
||||||
self.print_path(&node.path, false, 0)?;
|
self.print_path(&node.path, false, 0, false)?;
|
||||||
word(&mut self.s, "! ")?;
|
word(&mut self.s, "! ")?;
|
||||||
self.cbox(INDENT_UNIT)?;
|
self.cbox(INDENT_UNIT)?;
|
||||||
self.popen()?;
|
self.popen()?;
|
||||||
|
@ -1607,7 +1610,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
ast::ImplItemKind::Macro(codemap::Spanned { ref node, .. }) => {
|
ast::ImplItemKind::Macro(codemap::Spanned { ref node, .. }) => {
|
||||||
// code copied from ItemKind::Mac:
|
// code copied from ItemKind::Mac:
|
||||||
try!(self.print_path(&node.path, false, 0));
|
try!(self.print_path(&node.path, false, 0, false));
|
||||||
try!(word(&mut self.s, "! "));
|
try!(word(&mut self.s, "! "));
|
||||||
try!(self.cbox(INDENT_UNIT));
|
try!(self.cbox(INDENT_UNIT));
|
||||||
try!(self.popen());
|
try!(self.popen());
|
||||||
|
@ -1793,7 +1796,7 @@ impl<'a> State<'a> {
|
||||||
|
|
||||||
pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken)
|
pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken)
|
||||||
-> io::Result<()> {
|
-> io::Result<()> {
|
||||||
try!(self.print_path(&m.node.path, false, 0));
|
try!(self.print_path(&m.node.path, false, 0, false));
|
||||||
try!(word(&mut self.s, "!"));
|
try!(word(&mut self.s, "!"));
|
||||||
match delim {
|
match delim {
|
||||||
token::Paren => try!(self.popen()),
|
token::Paren => try!(self.popen()),
|
||||||
|
@ -1885,7 +1888,7 @@ impl<'a> State<'a> {
|
||||||
fields: &[ast::Field],
|
fields: &[ast::Field],
|
||||||
wth: &Option<P<ast::Expr>>,
|
wth: &Option<P<ast::Expr>>,
|
||||||
attrs: &[Attribute]) -> io::Result<()> {
|
attrs: &[Attribute]) -> io::Result<()> {
|
||||||
try!(self.print_path(path, true, 0));
|
try!(self.print_path(path, true, 0, false));
|
||||||
try!(word(&mut self.s, "{"));
|
try!(word(&mut self.s, "{"));
|
||||||
try!(self.print_inner_attributes_inline(attrs));
|
try!(self.print_inner_attributes_inline(attrs));
|
||||||
try!(self.commasep_cmnt(
|
try!(self.commasep_cmnt(
|
||||||
|
@ -2186,7 +2189,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprKind::Path(None, ref path) => {
|
ast::ExprKind::Path(None, ref path) => {
|
||||||
try!(self.print_path(path, true, 0))
|
try!(self.print_path(path, true, 0, false))
|
||||||
}
|
}
|
||||||
ast::ExprKind::Path(Some(ref qself), ref path) => {
|
ast::ExprKind::Path(Some(ref qself), ref path) => {
|
||||||
try!(self.print_qpath(path, qself, true))
|
try!(self.print_qpath(path, qself, true))
|
||||||
|
@ -2334,23 +2337,25 @@ impl<'a> State<'a> {
|
||||||
fn print_path(&mut self,
|
fn print_path(&mut self,
|
||||||
path: &ast::Path,
|
path: &ast::Path,
|
||||||
colons_before_params: bool,
|
colons_before_params: bool,
|
||||||
depth: usize)
|
depth: usize,
|
||||||
|
defaults_to_global: bool)
|
||||||
-> io::Result<()>
|
-> io::Result<()>
|
||||||
{
|
{
|
||||||
try!(self.maybe_print_comment(path.span.lo));
|
try!(self.maybe_print_comment(path.span.lo));
|
||||||
|
|
||||||
let mut first = !path.global;
|
let mut segments = path.segments[..path.segments.len()-depth].iter();
|
||||||
for segment in &path.segments[..path.segments.len()-depth] {
|
if defaults_to_global && path.is_global() {
|
||||||
if first {
|
segments.next();
|
||||||
first = false
|
}
|
||||||
} else {
|
for (i, segment) in segments.enumerate() {
|
||||||
|
if i > 0 {
|
||||||
try!(word(&mut self.s, "::"))
|
try!(word(&mut self.s, "::"))
|
||||||
}
|
}
|
||||||
|
if segment.identifier.name != keywords::CrateRoot.name() {
|
||||||
try!(self.print_ident(segment.identifier));
|
try!(self.print_ident(segment.identifier));
|
||||||
|
if let Some(ref parameters) = segment.parameters {
|
||||||
if let Some(ref parameters) = segment.parameters {
|
try!(self.print_path_parameters(parameters, colons_before_params));
|
||||||
try!(self.print_path_parameters(parameters, colons_before_params))
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2369,7 +2374,7 @@ impl<'a> State<'a> {
|
||||||
try!(space(&mut self.s));
|
try!(space(&mut self.s));
|
||||||
try!(self.word_space("as"));
|
try!(self.word_space("as"));
|
||||||
let depth = path.segments.len() - qself.position;
|
let depth = path.segments.len() - qself.position;
|
||||||
try!(self.print_path(&path, false, depth));
|
try!(self.print_path(&path, false, depth, false));
|
||||||
}
|
}
|
||||||
try!(word(&mut self.s, ">"));
|
try!(word(&mut self.s, ">"));
|
||||||
try!(word(&mut self.s, "::"));
|
try!(word(&mut self.s, "::"));
|
||||||
|
@ -2472,7 +2477,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PatKind::TupleStruct(ref path, ref elts, ddpos) => {
|
PatKind::TupleStruct(ref path, ref elts, ddpos) => {
|
||||||
try!(self.print_path(path, true, 0));
|
try!(self.print_path(path, true, 0, false));
|
||||||
try!(self.popen());
|
try!(self.popen());
|
||||||
if let Some(ddpos) = ddpos {
|
if let Some(ddpos) = ddpos {
|
||||||
try!(self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p)));
|
try!(self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p)));
|
||||||
|
@ -2490,13 +2495,13 @@ impl<'a> State<'a> {
|
||||||
try!(self.pclose());
|
try!(self.pclose());
|
||||||
}
|
}
|
||||||
PatKind::Path(None, ref path) => {
|
PatKind::Path(None, ref path) => {
|
||||||
try!(self.print_path(path, true, 0));
|
try!(self.print_path(path, true, 0, false));
|
||||||
}
|
}
|
||||||
PatKind::Path(Some(ref qself), ref path) => {
|
PatKind::Path(Some(ref qself), ref path) => {
|
||||||
try!(self.print_qpath(path, qself, false));
|
try!(self.print_qpath(path, qself, false));
|
||||||
}
|
}
|
||||||
PatKind::Struct(ref path, ref fields, etc) => {
|
PatKind::Struct(ref path, ref fields, etc) => {
|
||||||
try!(self.print_path(path, true, 0));
|
try!(self.print_path(path, true, 0, false));
|
||||||
try!(self.nbsp());
|
try!(self.nbsp());
|
||||||
try!(self.word_space("{"));
|
try!(self.word_space("{"));
|
||||||
try!(self.commasep_cmnt(
|
try!(self.commasep_cmnt(
|
||||||
|
@ -2843,7 +2848,7 @@ impl<'a> State<'a> {
|
||||||
try!(self.print_lifetime_bounds(lifetime, bounds));
|
try!(self.print_lifetime_bounds(lifetime, bounds));
|
||||||
}
|
}
|
||||||
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ref path, ref ty, ..}) => {
|
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ref path, ref ty, ..}) => {
|
||||||
try!(self.print_path(path, false, 0));
|
try!(self.print_path(path, false, 0, false));
|
||||||
try!(space(&mut self.s));
|
try!(space(&mut self.s));
|
||||||
try!(self.word_space("="));
|
try!(self.word_space("="));
|
||||||
try!(self.print_type(&ty));
|
try!(self.print_type(&ty));
|
||||||
|
@ -2857,7 +2862,7 @@ impl<'a> State<'a> {
|
||||||
pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> io::Result<()> {
|
pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> io::Result<()> {
|
||||||
match vp.node {
|
match vp.node {
|
||||||
ast::ViewPathSimple(ident, ref path) => {
|
ast::ViewPathSimple(ident, ref path) => {
|
||||||
try!(self.print_path(path, false, 0));
|
try!(self.print_path(path, false, 0, true));
|
||||||
|
|
||||||
if path.segments.last().unwrap().identifier.name !=
|
if path.segments.last().unwrap().identifier.name !=
|
||||||
ident.name {
|
ident.name {
|
||||||
|
@ -2870,7 +2875,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ViewPathGlob(ref path) => {
|
ast::ViewPathGlob(ref path) => {
|
||||||
try!(self.print_path(path, false, 0));
|
try!(self.print_path(path, false, 0, true));
|
||||||
word(&mut self.s, "::*")
|
word(&mut self.s, "::*")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2878,7 +2883,7 @@ impl<'a> State<'a> {
|
||||||
if path.segments.is_empty() {
|
if path.segments.is_empty() {
|
||||||
try!(word(&mut self.s, "{"));
|
try!(word(&mut self.s, "{"));
|
||||||
} else {
|
} else {
|
||||||
try!(self.print_path(path, false, 0));
|
try!(self.print_path(path, false, 0, true));
|
||||||
try!(word(&mut self.s, "::{"));
|
try!(word(&mut self.s, "::{"));
|
||||||
}
|
}
|
||||||
try!(self.commasep(Inconsistent, &idents[..], |s, w| {
|
try!(self.commasep(Inconsistent, &idents[..], |s, w| {
|
||||||
|
|
|
@ -80,8 +80,7 @@ pub fn maybe_inject_crates_ref(sess: &ParseSess,
|
||||||
}],
|
}],
|
||||||
vis: ast::Visibility::Inherited,
|
vis: ast::Visibility::Inherited,
|
||||||
node: ast::ItemKind::Use(P(codemap::dummy_spanned(ast::ViewPathGlob(ast::Path {
|
node: ast::ItemKind::Use(P(codemap::dummy_spanned(ast::ViewPathGlob(ast::Path {
|
||||||
global: false,
|
segments: ["{{root}}", name, "prelude", "v1"].into_iter().map(|name| {
|
||||||
segments: vec![name, "prelude", "v1"].into_iter().map(|name| {
|
|
||||||
ast::Ident::from_str(name).into()
|
ast::Ident::from_str(name).into()
|
||||||
}).collect(),
|
}).collect(),
|
||||||
span: span,
|
span: span,
|
||||||
|
|
|
@ -221,6 +221,9 @@ declare_keywords! {
|
||||||
(53, Default, "default")
|
(53, Default, "default")
|
||||||
(54, StaticLifetime, "'static")
|
(54, StaticLifetime, "'static")
|
||||||
(55, Union, "union")
|
(55, Union, "union")
|
||||||
|
|
||||||
|
// A virtual keyword that resolves to the crate root when used in a lexical scope.
|
||||||
|
(56, CrateRoot, "{{root}}")
|
||||||
}
|
}
|
||||||
|
|
||||||
// If an interner exists in TLS, return it. Otherwise, prepare a fresh one.
|
// If an interner exists in TLS, return it. Otherwise, prepare a fresh one.
|
||||||
|
|
|
@ -579,7 +579,6 @@ fn nospan<T>(t: T) -> codemap::Spanned<T> {
|
||||||
fn path_node(ids: Vec<Ident>) -> ast::Path {
|
fn path_node(ids: Vec<Ident>) -> ast::Path {
|
||||||
ast::Path {
|
ast::Path {
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
global: false,
|
|
||||||
segments: ids.into_iter().map(Into::into).collect(),
|
segments: ids.into_iter().map(Into::into).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,6 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
|
||||||
fn path(&self) -> ast::Path {
|
fn path(&self) -> ast::Path {
|
||||||
ast::Path {
|
ast::Path {
|
||||||
span: self.span,
|
span: self.span,
|
||||||
global: false,
|
|
||||||
segments: vec![self.ident.into()],
|
segments: vec![self.ident.into()],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -363,15 +363,12 @@ fn find_type_parameters(ty: &ast::Ty,
|
||||||
|
|
||||||
impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> {
|
impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> {
|
||||||
fn visit_ty(&mut self, ty: &'a ast::Ty) {
|
fn visit_ty(&mut self, ty: &'a ast::Ty) {
|
||||||
match ty.node {
|
if let ast::TyKind::Path(_, ref path) = ty.node {
|
||||||
ast::TyKind::Path(_, ref path) if !path.global => {
|
if let Some(segment) = path.segments.first() {
|
||||||
if let Some(segment) = path.segments.first() {
|
if self.ty_param_names.contains(&segment.identifier.name) {
|
||||||
if self.ty_param_names.contains(&segment.identifier.name) {
|
self.types.push(P(ty.clone()));
|
||||||
self.types.push(P(ty.clone()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
visit::walk_ty(self, ty)
|
visit::walk_ty(self, ty)
|
||||||
|
|
|
@ -16,5 +16,5 @@ fn main() {
|
||||||
|
|
||||||
// Make sure primitive type fallback doesn't work with global paths
|
// Make sure primitive type fallback doesn't work with global paths
|
||||||
let _: ::u8;
|
let _: ::u8;
|
||||||
//~^ ERROR type name `u8` is undefined or not in scope
|
//~^ ERROR type name `::u8` is undefined or not in scope
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue