Optimize ast::PathSegment
.
This commit is contained in:
parent
dcae8bfb40
commit
8e61ff25d8
14 changed files with 86 additions and 210 deletions
|
@ -433,13 +433,19 @@ impl<'a> LoweringContext<'a> {
|
||||||
segment: &PathSegment,
|
segment: &PathSegment,
|
||||||
param_mode: ParamMode)
|
param_mode: ParamMode)
|
||||||
-> hir::PathSegment {
|
-> hir::PathSegment {
|
||||||
let parameters = match segment.parameters {
|
let parameters = if let Some(ref parameters) = segment.parameters {
|
||||||
PathParameters::AngleBracketed(ref data) => {
|
match **parameters {
|
||||||
let data = self.lower_angle_bracketed_parameter_data(data, param_mode);
|
PathParameters::AngleBracketed(ref data) => {
|
||||||
hir::AngleBracketedParameters(data)
|
let data = self.lower_angle_bracketed_parameter_data(data, param_mode);
|
||||||
|
hir::AngleBracketedParameters(data)
|
||||||
|
}
|
||||||
|
PathParameters::Parenthesized(ref data) => {
|
||||||
|
hir::ParenthesizedParameters(self.lower_parenthesized_parameter_data(data))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PathParameters::Parenthesized(ref data) =>
|
} else {
|
||||||
hir::ParenthesizedParameters(self.lower_parenthesized_parameter_data(data)),
|
let data = self.lower_angle_bracketed_parameter_data(&Default::default(), param_mode);
|
||||||
|
hir::AngleBracketedParameters(data)
|
||||||
};
|
};
|
||||||
|
|
||||||
hir::PathSegment {
|
hir::PathSegment {
|
||||||
|
|
|
@ -171,7 +171,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
match item.node {
|
match item.node {
|
||||||
ItemKind::Use(ref view_path) => {
|
ItemKind::Use(ref view_path) => {
|
||||||
let path = view_path.node.path();
|
let path = view_path.node.path();
|
||||||
if !path.segments.iter().all(|segment| segment.parameters.is_empty()) {
|
if path.segments.iter().any(|segment| segment.parameters.is_some()) {
|
||||||
self.err_handler()
|
self.err_handler()
|
||||||
.span_err(path.span, "type or lifetime parameters in import path");
|
.span_err(path.span, "type or lifetime parameters in import path");
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
fn visit_vis(&mut self, vis: &'a Visibility) {
|
fn visit_vis(&mut self, vis: &'a Visibility) {
|
||||||
match *vis {
|
match *vis {
|
||||||
Visibility::Restricted { ref path, .. } => {
|
Visibility::Restricted { ref path, .. } => {
|
||||||
if !path.segments.iter().all(|segment| segment.parameters.is_empty()) {
|
if !path.segments.iter().all(|segment| segment.parameters.is_none()) {
|
||||||
self.err_handler()
|
self.err_handler()
|
||||||
.span_err(path.span, "type or lifetime parameters in visibility path");
|
.span_err(path.span, "type or lifetime parameters in visibility path");
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ use syntax::ast::{Arm, BindingMode, Block, Crate, Expr, ExprKind};
|
||||||
use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, Generics};
|
use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, Generics};
|
||||||
use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
|
use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
|
||||||
use syntax::ast::{Local, Mutability, Pat, PatKind, Path};
|
use syntax::ast::{Local, Mutability, Pat, PatKind, Path};
|
||||||
use syntax::ast::{PathSegment, PathParameters, QSelf, TraitItemKind, TraitRef, Ty, TyKind};
|
use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
|
||||||
|
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
use errors::DiagnosticBuilder;
|
use errors::DiagnosticBuilder;
|
||||||
|
@ -2960,14 +2960,9 @@ impl<'a> Resolver<'a> {
|
||||||
if ident.name == lookup_name && ns == namespace {
|
if ident.name == lookup_name && ns == namespace {
|
||||||
if filter_fn(name_binding.def()) {
|
if filter_fn(name_binding.def()) {
|
||||||
// create the path
|
// create the path
|
||||||
let params = PathParameters::none();
|
|
||||||
let segment = PathSegment {
|
|
||||||
identifier: ident,
|
|
||||||
parameters: params,
|
|
||||||
};
|
|
||||||
let span = name_binding.span;
|
let span = name_binding.span;
|
||||||
let mut segms = path_segments.clone();
|
let mut segms = path_segments.clone();
|
||||||
segms.push(segment);
|
segms.push(ident.into());
|
||||||
let path = Path {
|
let path = Path {
|
||||||
span: span,
|
span: span,
|
||||||
global: false,
|
global: false,
|
||||||
|
@ -2990,10 +2985,7 @@ impl<'a> Resolver<'a> {
|
||||||
if let Some(module) = name_binding.module() {
|
if let Some(module) = name_binding.module() {
|
||||||
// form the path
|
// form the path
|
||||||
let mut path_segments = path_segments.clone();
|
let mut path_segments = path_segments.clone();
|
||||||
path_segments.push(PathSegment {
|
path_segments.push(ident.into());
|
||||||
identifier: ident,
|
|
||||||
parameters: PathParameters::none(),
|
|
||||||
});
|
|
||||||
|
|
||||||
if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
|
if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
|
||||||
// add the module to the lookup
|
// add the module to the lookup
|
||||||
|
|
|
@ -183,9 +183,9 @@ 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, global, span } = *path;
|
||||||
if segments.iter().any(|segment| !segment.parameters.is_empty()) {
|
if segments.iter().any(|segment| segment.parameters.is_some()) {
|
||||||
let kind =
|
let kind =
|
||||||
if segments.last().unwrap().parameters.is_empty() { "module" } else { "macro" };
|
if segments.last().unwrap().parameters.is_some() { "macro" } else { "module" };
|
||||||
let msg = format!("type parameters are not allowed on {}s", kind);
|
let msg = format!("type parameters are not allowed on {}s", kind);
|
||||||
self.session.span_err(path.span, &msg);
|
self.session.span_err(path.span, &msg);
|
||||||
return Err(Determinacy::Determined);
|
return Err(Determinacy::Determined);
|
||||||
|
|
|
@ -137,12 +137,7 @@ impl Path {
|
||||||
Path {
|
Path {
|
||||||
span: s,
|
span: s,
|
||||||
global: false,
|
global: false,
|
||||||
segments: vec![
|
segments: vec![identifier.into()],
|
||||||
PathSegment {
|
|
||||||
identifier: identifier,
|
|
||||||
parameters: PathParameters::none()
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +155,15 @@ pub struct PathSegment {
|
||||||
/// this is more than just simple syntactic sugar; the use of
|
/// this is more than just simple syntactic sugar; the use of
|
||||||
/// parens affects the region binding rules, so we preserve the
|
/// parens affects the region binding rules, so we preserve the
|
||||||
/// distinction.
|
/// distinction.
|
||||||
pub parameters: PathParameters,
|
/// The `Option<P<..>>` wrapper is purely a size optimization;
|
||||||
|
/// `None` is used to represent both `Path` and `Path<>`.
|
||||||
|
pub parameters: Option<P<PathParameters>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Ident> for PathSegment {
|
||||||
|
fn from(id: Ident) -> Self {
|
||||||
|
PathSegment { identifier: id, parameters: None }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parameters of a path segment.
|
/// Parameters of a path segment.
|
||||||
|
@ -174,79 +177,8 @@ pub enum PathParameters {
|
||||||
Parenthesized(ParenthesizedParameterData),
|
Parenthesized(ParenthesizedParameterData),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PathParameters {
|
|
||||||
pub fn none() -> PathParameters {
|
|
||||||
PathParameters::AngleBracketed(AngleBracketedParameterData {
|
|
||||||
lifetimes: Vec::new(),
|
|
||||||
types: P::new(),
|
|
||||||
bindings: P::new(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
match *self {
|
|
||||||
PathParameters::AngleBracketed(ref data) => data.is_empty(),
|
|
||||||
|
|
||||||
// Even if the user supplied no types, something like
|
|
||||||
// `X()` is equivalent to `X<(),()>`.
|
|
||||||
PathParameters::Parenthesized(..) => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_lifetimes(&self) -> bool {
|
|
||||||
match *self {
|
|
||||||
PathParameters::AngleBracketed(ref data) => !data.lifetimes.is_empty(),
|
|
||||||
PathParameters::Parenthesized(_) => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_types(&self) -> bool {
|
|
||||||
match *self {
|
|
||||||
PathParameters::AngleBracketed(ref data) => !data.types.is_empty(),
|
|
||||||
PathParameters::Parenthesized(..) => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the types that the user wrote. Note that these do not necessarily map to the type
|
|
||||||
/// parameters in the parenthesized case.
|
|
||||||
pub fn types(&self) -> Vec<&P<Ty>> {
|
|
||||||
match *self {
|
|
||||||
PathParameters::AngleBracketed(ref data) => {
|
|
||||||
data.types.iter().collect()
|
|
||||||
}
|
|
||||||
PathParameters::Parenthesized(ref data) => {
|
|
||||||
data.inputs.iter()
|
|
||||||
.chain(data.output.iter())
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn lifetimes(&self) -> Vec<&Lifetime> {
|
|
||||||
match *self {
|
|
||||||
PathParameters::AngleBracketed(ref data) => {
|
|
||||||
data.lifetimes.iter().collect()
|
|
||||||
}
|
|
||||||
PathParameters::Parenthesized(_) => {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bindings(&self) -> Vec<&TypeBinding> {
|
|
||||||
match *self {
|
|
||||||
PathParameters::AngleBracketed(ref data) => {
|
|
||||||
data.bindings.iter().collect()
|
|
||||||
}
|
|
||||||
PathParameters::Parenthesized(_) => {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A path like `Foo<'a, T>`
|
/// A path like `Foo<'a, T>`
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Default)]
|
||||||
pub struct AngleBracketedParameterData {
|
pub struct AngleBracketedParameterData {
|
||||||
/// The lifetime parameters for this path segment.
|
/// The lifetime parameters for this path segment.
|
||||||
pub lifetimes: Vec<Lifetime>,
|
pub lifetimes: Vec<Lifetime>,
|
||||||
|
@ -258,9 +190,10 @@ pub struct AngleBracketedParameterData {
|
||||||
pub bindings: P<[TypeBinding]>,
|
pub bindings: P<[TypeBinding]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AngleBracketedParameterData {
|
impl Into<Option<P<PathParameters>>> for AngleBracketedParameterData {
|
||||||
fn is_empty(&self) -> bool {
|
fn into(self) -> Option<P<PathParameters>> {
|
||||||
self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty()
|
let empty = self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty();
|
||||||
|
if empty { None } else { Some(P(PathParameters::AngleBracketed(self))) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -322,21 +322,17 @@ 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()
|
let mut segments: Vec<ast::PathSegment> = idents.into_iter().map(Into::into).collect();
|
||||||
.map(|ident| {
|
let parameters = if lifetimes.is_empty() && types.is_empty() && bindings.is_empty() {
|
||||||
ast::PathSegment {
|
None
|
||||||
identifier: ident,
|
} else {
|
||||||
parameters: ast::PathParameters::none(),
|
Some(P(ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
|
||||||
}
|
|
||||||
}).collect();
|
|
||||||
segments.push(ast::PathSegment {
|
|
||||||
identifier: last_identifier,
|
|
||||||
parameters: ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
|
|
||||||
lifetimes: lifetimes,
|
lifetimes: lifetimes,
|
||||||
types: P::from_vec(types),
|
types: P::from_vec(types),
|
||||||
bindings: P::from_vec(bindings),
|
bindings: P::from_vec(bindings),
|
||||||
})
|
})))
|
||||||
});
|
};
|
||||||
|
segments.push(ast::PathSegment { identifier: last_identifier, parameters: parameters });
|
||||||
ast::Path {
|
ast::Path {
|
||||||
span: sp,
|
span: sp,
|
||||||
global: global,
|
global: global,
|
||||||
|
@ -367,13 +363,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
bindings: Vec<ast::TypeBinding>)
|
bindings: Vec<ast::TypeBinding>)
|
||||||
-> (ast::QSelf, ast::Path) {
|
-> (ast::QSelf, ast::Path) {
|
||||||
let mut path = trait_path;
|
let mut path = trait_path;
|
||||||
|
let parameters = ast::AngleBracketedParameterData {
|
||||||
|
lifetimes: lifetimes,
|
||||||
|
types: P::from_vec(types),
|
||||||
|
bindings: P::from_vec(bindings),
|
||||||
|
};
|
||||||
path.segments.push(ast::PathSegment {
|
path.segments.push(ast::PathSegment {
|
||||||
identifier: ident,
|
identifier: ident,
|
||||||
parameters: ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
|
parameters: Some(P(ast::PathParameters::AngleBracketed(parameters))),
|
||||||
lifetimes: lifetimes,
|
|
||||||
types: P::from_vec(types),
|
|
||||||
bindings: P::from_vec(bindings),
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
(ast::QSelf {
|
(ast::QSelf {
|
||||||
|
|
|
@ -438,7 +438,7 @@ pub fn noop_fold_path<T: Folder>(Path {global, segments, span}: Path, fld: &mut
|
||||||
global: global,
|
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: fld.fold_path_parameters(parameters),
|
parameters: parameters.map(|ps| ps.map(|ps| fld.fold_path_parameters(ps))),
|
||||||
}),
|
}),
|
||||||
span: fld.new_span(span)
|
span: fld.new_span(span)
|
||||||
}
|
}
|
||||||
|
|
|
@ -634,12 +634,7 @@ mod tests {
|
||||||
node: ast::ExprKind::Path(None, ast::Path {
|
node: ast::ExprKind::Path(None, ast::Path {
|
||||||
span: sp(0, 1),
|
span: sp(0, 1),
|
||||||
global: false,
|
global: false,
|
||||||
segments: vec![
|
segments: vec![Ident::from_str("a").into()],
|
||||||
ast::PathSegment {
|
|
||||||
identifier: Ident::from_str("a"),
|
|
||||||
parameters: ast::PathParameters::none(),
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
span: sp(0, 1),
|
span: sp(0, 1),
|
||||||
attrs: ThinVec::new(),
|
attrs: ThinVec::new(),
|
||||||
|
@ -651,19 +646,10 @@ mod tests {
|
||||||
P(ast::Expr {
|
P(ast::Expr {
|
||||||
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,
|
global: true,
|
||||||
segments: vec![
|
segments: vec![Ident::from_str("a").into(), Ident::from_str("b").into()],
|
||||||
ast::PathSegment {
|
}),
|
||||||
identifier: Ident::from_str("a"),
|
|
||||||
parameters: ast::PathParameters::none(),
|
|
||||||
},
|
|
||||||
ast::PathSegment {
|
|
||||||
identifier: Ident::from_str("b"),
|
|
||||||
parameters: ast::PathParameters::none(),
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
span: sp(0, 6),
|
span: sp(0, 6),
|
||||||
attrs: ThinVec::new(),
|
attrs: ThinVec::new(),
|
||||||
}))
|
}))
|
||||||
|
@ -772,12 +758,7 @@ mod tests {
|
||||||
node:ast::ExprKind::Path(None, ast::Path{
|
node:ast::ExprKind::Path(None, ast::Path{
|
||||||
span: sp(7, 8),
|
span: sp(7, 8),
|
||||||
global: false,
|
global: false,
|
||||||
segments: vec![
|
segments: vec![Ident::from_str("d").into()],
|
||||||
ast::PathSegment {
|
|
||||||
identifier: Ident::from_str("d"),
|
|
||||||
parameters: ast::PathParameters::none(),
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
span:sp(7,8),
|
span:sp(7,8),
|
||||||
attrs: ThinVec::new(),
|
attrs: ThinVec::new(),
|
||||||
|
@ -795,12 +776,7 @@ mod tests {
|
||||||
node: ast::ExprKind::Path(None, ast::Path {
|
node: ast::ExprKind::Path(None, ast::Path {
|
||||||
span:sp(0,1),
|
span:sp(0,1),
|
||||||
global:false,
|
global:false,
|
||||||
segments: vec![
|
segments: vec![Ident::from_str("b").into()],
|
||||||
ast::PathSegment {
|
|
||||||
identifier: Ident::from_str("b"),
|
|
||||||
parameters: ast::PathParameters::none(),
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
span: sp(0,1),
|
span: sp(0,1),
|
||||||
attrs: ThinVec::new()})),
|
attrs: ThinVec::new()})),
|
||||||
|
@ -842,12 +818,7 @@ mod tests {
|
||||||
node: ast::TyKind::Path(None, ast::Path{
|
node: ast::TyKind::Path(None, ast::Path{
|
||||||
span:sp(10,13),
|
span:sp(10,13),
|
||||||
global:false,
|
global:false,
|
||||||
segments: vec![
|
segments: vec![Ident::from_str("i32").into()],
|
||||||
ast::PathSegment {
|
|
||||||
identifier: Ident::from_str("i32"),
|
|
||||||
parameters: ast::PathParameters::none(),
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
span:sp(10,13)
|
span:sp(10,13)
|
||||||
}),
|
}),
|
||||||
|
@ -890,13 +861,7 @@ mod tests {
|
||||||
ast::Path{
|
ast::Path{
|
||||||
span:sp(17,18),
|
span:sp(17,18),
|
||||||
global:false,
|
global:false,
|
||||||
segments: vec![
|
segments: vec![Ident::from_str("b").into()],
|
||||||
ast::PathSegment {
|
|
||||||
identifier: Ident::from_str("b"),
|
|
||||||
parameters:
|
|
||||||
ast::PathParameters::none(),
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
span: sp(17,18),
|
span: sp(17,18),
|
||||||
attrs: ThinVec::new()})),
|
attrs: ThinVec::new()})),
|
||||||
|
|
|
@ -1705,12 +1705,11 @@ impl<'a> Parser<'a> {
|
||||||
// Parse types, optionally.
|
// Parse types, optionally.
|
||||||
let parameters = if self.eat_lt() {
|
let parameters = if self.eat_lt() {
|
||||||
let (lifetimes, types, bindings) = self.parse_generic_values_after_lt()?;
|
let (lifetimes, types, bindings) = self.parse_generic_values_after_lt()?;
|
||||||
|
ast::AngleBracketedParameterData {
|
||||||
ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
|
|
||||||
lifetimes: lifetimes,
|
lifetimes: lifetimes,
|
||||||
types: P::from_vec(types),
|
types: P::from_vec(types),
|
||||||
bindings: P::from_vec(bindings),
|
bindings: P::from_vec(bindings),
|
||||||
})
|
}.into()
|
||||||
} else if self.eat(&token::OpenDelim(token::Paren)) {
|
} else if self.eat(&token::OpenDelim(token::Paren)) {
|
||||||
let lo = self.prev_span.lo;
|
let lo = self.prev_span.lo;
|
||||||
|
|
||||||
|
@ -1727,18 +1726,17 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
let hi = self.prev_span.hi;
|
let hi = self.prev_span.hi;
|
||||||
|
|
||||||
ast::PathParameters::Parenthesized(ast::ParenthesizedParameterData {
|
Some(P(ast::PathParameters::Parenthesized(ast::ParenthesizedParameterData {
|
||||||
span: mk_sp(lo, hi),
|
span: mk_sp(lo, hi),
|
||||||
inputs: inputs,
|
inputs: inputs,
|
||||||
output: output_ty,
|
output: output_ty,
|
||||||
})
|
})))
|
||||||
} else {
|
} else {
|
||||||
ast::PathParameters::none()
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
// Assemble and push the result.
|
// Assemble and push the result.
|
||||||
segments.push(ast::PathSegment { identifier: identifier,
|
segments.push(ast::PathSegment { identifier: identifier, parameters: parameters });
|
||||||
parameters: parameters });
|
|
||||||
|
|
||||||
// Continue only if we see a `::`
|
// Continue only if we see a `::`
|
||||||
if !self.eat(&token::ModSep) {
|
if !self.eat(&token::ModSep) {
|
||||||
|
@ -1757,10 +1755,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
// If we do not see a `::`, stop.
|
// If we do not see a `::`, stop.
|
||||||
if !self.eat(&token::ModSep) {
|
if !self.eat(&token::ModSep) {
|
||||||
segments.push(ast::PathSegment {
|
segments.push(identifier.into());
|
||||||
identifier: identifier,
|
|
||||||
parameters: ast::PathParameters::none()
|
|
||||||
});
|
|
||||||
return Ok(segments);
|
return Ok(segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1768,14 +1763,13 @@ impl<'a> Parser<'a> {
|
||||||
if self.eat_lt() {
|
if self.eat_lt() {
|
||||||
// Consumed `a::b::<`, go look for types
|
// Consumed `a::b::<`, go look for types
|
||||||
let (lifetimes, types, bindings) = self.parse_generic_values_after_lt()?;
|
let (lifetimes, types, bindings) = self.parse_generic_values_after_lt()?;
|
||||||
let parameters = ast::AngleBracketedParameterData {
|
|
||||||
lifetimes: lifetimes,
|
|
||||||
types: P::from_vec(types),
|
|
||||||
bindings: P::from_vec(bindings),
|
|
||||||
};
|
|
||||||
segments.push(ast::PathSegment {
|
segments.push(ast::PathSegment {
|
||||||
identifier: identifier,
|
identifier: identifier,
|
||||||
parameters: ast::PathParameters::AngleBracketed(parameters),
|
parameters: ast::AngleBracketedParameterData {
|
||||||
|
lifetimes: lifetimes,
|
||||||
|
types: P::from_vec(types),
|
||||||
|
bindings: P::from_vec(bindings),
|
||||||
|
}.into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Consumed `a::b::<T,U>`, check for `::` before proceeding
|
// Consumed `a::b::<T,U>`, check for `::` before proceeding
|
||||||
|
@ -1784,10 +1778,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Consumed `a::`, go look for `b`
|
// Consumed `a::`, go look for `b`
|
||||||
segments.push(ast::PathSegment {
|
segments.push(identifier.into());
|
||||||
identifier: identifier,
|
|
||||||
parameters: ast::PathParameters::none(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1802,10 +1793,7 @@ impl<'a> Parser<'a> {
|
||||||
let identifier = self.parse_path_segment_ident()?;
|
let identifier = self.parse_path_segment_ident()?;
|
||||||
|
|
||||||
// Assemble and push the result.
|
// Assemble and push the result.
|
||||||
segments.push(ast::PathSegment {
|
segments.push(identifier.into());
|
||||||
identifier: identifier,
|
|
||||||
parameters: ast::PathParameters::none()
|
|
||||||
});
|
|
||||||
|
|
||||||
// If we do not see a `::` or see `::{`/`::*`, stop.
|
// If we do not see a `::` or see `::{`/`::*`, stop.
|
||||||
if !self.check(&token::ModSep) || self.is_import_coupler() {
|
if !self.check(&token::ModSep) || self.is_import_coupler() {
|
||||||
|
|
|
@ -2349,7 +2349,9 @@ impl<'a> State<'a> {
|
||||||
|
|
||||||
try!(self.print_ident(segment.identifier));
|
try!(self.print_ident(segment.identifier));
|
||||||
|
|
||||||
try!(self.print_path_parameters(&segment.parameters, colons_before_params));
|
if let Some(ref parameters) = segment.parameters {
|
||||||
|
try!(self.print_path_parameters(parameters, colons_before_params))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -2373,7 +2375,10 @@ impl<'a> State<'a> {
|
||||||
try!(word(&mut self.s, "::"));
|
try!(word(&mut self.s, "::"));
|
||||||
let item_segment = path.segments.last().unwrap();
|
let item_segment = path.segments.last().unwrap();
|
||||||
try!(self.print_ident(item_segment.identifier));
|
try!(self.print_ident(item_segment.identifier));
|
||||||
self.print_path_parameters(&item_segment.parameters, colons_before_params)
|
match item_segment.parameters {
|
||||||
|
Some(ref parameters) => self.print_path_parameters(parameters, colons_before_params),
|
||||||
|
None => Ok(()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_path_parameters(&mut self,
|
fn print_path_parameters(&mut self,
|
||||||
|
@ -2381,10 +2386,6 @@ impl<'a> State<'a> {
|
||||||
colons_before_params: bool)
|
colons_before_params: bool)
|
||||||
-> io::Result<()>
|
-> io::Result<()>
|
||||||
{
|
{
|
||||||
if parameters.is_empty() {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
if colons_before_params {
|
if colons_before_params {
|
||||||
try!(word(&mut self.s, "::"))
|
try!(word(&mut self.s, "::"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,9 +81,8 @@ 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,
|
global: false,
|
||||||
segments: vec![name, "prelude", "v1"].into_iter().map(|name| ast::PathSegment {
|
segments: vec![name, "prelude", "v1"].into_iter().map(|name| {
|
||||||
identifier: ast::Ident::from_str(name),
|
ast::Ident::from_str(name).into()
|
||||||
parameters: ast::PathParameters::none(),
|
|
||||||
}).collect(),
|
}).collect(),
|
||||||
span: span,
|
span: span,
|
||||||
})))),
|
})))),
|
||||||
|
|
|
@ -580,10 +580,7 @@ fn path_node(ids: Vec<Ident>) -> ast::Path {
|
||||||
ast::Path {
|
ast::Path {
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
global: false,
|
global: false,
|
||||||
segments: ids.into_iter().map(|identifier| ast::PathSegment {
|
segments: ids.into_iter().map(Into::into).collect(),
|
||||||
identifier: identifier,
|
|
||||||
parameters: ast::PathParameters::none(),
|
|
||||||
}).collect()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -383,7 +383,9 @@ pub fn walk_path_segment<'a, V: Visitor<'a>>(visitor: &mut V,
|
||||||
path_span: Span,
|
path_span: Span,
|
||||||
segment: &'a PathSegment) {
|
segment: &'a PathSegment) {
|
||||||
visitor.visit_ident(path_span, segment.identifier);
|
visitor.visit_ident(path_span, segment.identifier);
|
||||||
visitor.visit_path_parameters(path_span, &segment.parameters);
|
if let Some(ref parameters) = segment.parameters {
|
||||||
|
visitor.visit_path_parameters(path_span, parameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_path_parameters<'a, V>(visitor: &mut V,
|
pub fn walk_path_parameters<'a, V>(visitor: &mut V,
|
||||||
|
|
|
@ -59,14 +59,10 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
|
||||||
|
|
||||||
impl Result {
|
impl Result {
|
||||||
fn path(&self) -> ast::Path {
|
fn path(&self) -> ast::Path {
|
||||||
let segment = ast::PathSegment {
|
|
||||||
identifier: self.ident,
|
|
||||||
parameters: ast::PathParameters::none(),
|
|
||||||
};
|
|
||||||
ast::Path {
|
ast::Path {
|
||||||
span: self.span,
|
span: self.span,
|
||||||
global: false,
|
global: false,
|
||||||
segments: vec![segment],
|
segments: vec![self.ident.into()],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue