提交 8e61ff25 编写于 作者: J Jeffrey Seyfried

Optimize `ast::PathSegment`.

上级 dcae8bfb
...@@ -433,13 +433,19 @@ fn lower_path_segment(&mut self, ...@@ -433,13 +433,19 @@ fn lower_path_segment(&mut self,
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 @@ fn visit_item(&mut self, item: &'a Item) { ...@@ -171,7 +171,7 @@ fn visit_item(&mut self, item: &'a Item) {
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 @@ fn visit_foreign_item(&mut self, fi: &'a ForeignItem) { ...@@ -275,7 +275,7 @@ fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
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 @@ ...@@ -62,7 +62,7 @@
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 @@ fn lookup_candidates<FilterFn>(&mut self, ...@@ -2960,14 +2960,9 @@ fn lookup_candidates<FilterFn>(&mut self,
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 @@ fn lookup_candidates<FilterFn>(&mut self, ...@@ -2990,10 +2985,7 @@ fn lookup_candidates<FilterFn>(&mut self,
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 @@ fn find_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>) -> Option<ast::At ...@@ -183,9 +183,9 @@ fn find_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>) -> Option<ast::At
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 @@ pub fn from_ident(s: Span, identifier: Ident) -> Path { ...@@ -137,12 +137,7 @@ pub fn from_ident(s: Span, identifier: Ident) -> 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 { ...@@ -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 { ...@@ -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 { ...@@ -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 @@ fn path_all(&self, ...@@ -322,21 +322,17 @@ fn path_all(&self,
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 @@ fn qpath_all(&self, ...@@ -367,13 +363,14 @@ fn qpath_all(&self,
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 ...@@ -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 @@ fn sp(a: u32, b: u32) -> Span { ...@@ -634,12 +634,7 @@ fn sp(a: u32, b: u32) -> Span {
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 @@ fn sp(a: u32, b: u32) -> Span { ...@@ -651,19 +646,10 @@ fn sp(a: u32, b: u32) -> Span {
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 @@ fn string_to_tts_1() { ...@@ -772,12 +758,7 @@ fn string_to_tts_1() {
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 @@ fn string_to_tts_1() { ...@@ -795,12 +776,7 @@ fn string_to_tts_1() {
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 @@ fn parser_done(p: Parser){ ...@@ -842,12 +818,7 @@ fn parser_done(p: Parser){
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 @@ fn parser_done(p: Parser){ ...@@ -890,13 +861,7 @@ fn parser_done(p: Parser){
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 @@ pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::Pat ...@@ -1705,12 +1705,11 @@ pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::Pat
// 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 @@ pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::Pat ...@@ -1727,18 +1726,17 @@ pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::Pat
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 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSe ...@@ -1757,10 +1755,7 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSe
// 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 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSe ...@@ -1768,14 +1763,13 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSe
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 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSe ...@@ -1784,10 +1778,7 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSe
} }
} 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 @@ pub fn parse_path_segments_without_types(&mut self) ...@@ -1802,10 +1793,7 @@ pub fn parse_path_segments_without_types(&mut self)
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 @@ fn print_path(&mut self, ...@@ -2349,7 +2349,9 @@ fn print_path(&mut self,
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 @@ fn print_qpath(&mut self, ...@@ -2373,7 +2375,10 @@ fn print_qpath(&mut self,
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 @@ fn print_path_parameters(&mut self, ...@@ -2381,10 +2386,6 @@ fn print_path_parameters(&mut self,
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, ...@@ -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 { ...@@ -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, ...@@ -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 @@ struct Result { ...@@ -59,14 +59,10 @@ struct Result {
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()],
} }
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册