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,
|
||||
param_mode: ParamMode)
|
||||
-> hir::PathSegment {
|
||||
let parameters = match segment.parameters {
|
||||
let parameters = if let Some(ref parameters) = segment.parameters {
|
||||
match **parameters {
|
||||
PathParameters::AngleBracketed(ref 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) => {
|
||||
hir::ParenthesizedParameters(self.lower_parenthesized_parameter_data(data))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let data = self.lower_angle_bracketed_parameter_data(&Default::default(), param_mode);
|
||||
hir::AngleBracketedParameters(data)
|
||||
};
|
||||
|
||||
hir::PathSegment {
|
||||
|
|
|
@ -171,7 +171,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
match item.node {
|
||||
ItemKind::Use(ref view_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()
|
||||
.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) {
|
||||
match *vis {
|
||||
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()
|
||||
.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::{Item, ItemKind, ImplItem, ImplItemKind};
|
||||
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 errors::DiagnosticBuilder;
|
||||
|
@ -2960,14 +2960,9 @@ impl<'a> Resolver<'a> {
|
|||
if ident.name == lookup_name && ns == namespace {
|
||||
if filter_fn(name_binding.def()) {
|
||||
// create the path
|
||||
let params = PathParameters::none();
|
||||
let segment = PathSegment {
|
||||
identifier: ident,
|
||||
parameters: params,
|
||||
};
|
||||
let span = name_binding.span;
|
||||
let mut segms = path_segments.clone();
|
||||
segms.push(segment);
|
||||
segms.push(ident.into());
|
||||
let path = Path {
|
||||
span: span,
|
||||
global: false,
|
||||
|
@ -2990,10 +2985,7 @@ impl<'a> Resolver<'a> {
|
|||
if let Some(module) = name_binding.module() {
|
||||
// form the path
|
||||
let mut path_segments = path_segments.clone();
|
||||
path_segments.push(PathSegment {
|
||||
identifier: ident,
|
||||
parameters: PathParameters::none(),
|
||||
});
|
||||
path_segments.push(ident.into());
|
||||
|
||||
if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
|
||||
// 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)
|
||||
-> Result<Rc<SyntaxExtension>, Determinacy> {
|
||||
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 =
|
||||
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);
|
||||
self.session.span_err(path.span, &msg);
|
||||
return Err(Determinacy::Determined);
|
||||
|
|
|
@ -137,12 +137,7 @@ impl Path {
|
|||
Path {
|
||||
span: s,
|
||||
global: false,
|
||||
segments: vec![
|
||||
PathSegment {
|
||||
identifier: identifier,
|
||||
parameters: PathParameters::none()
|
||||
}
|
||||
],
|
||||
segments: vec![identifier.into()],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +155,15 @@ pub struct PathSegment {
|
|||
/// this is more than just simple syntactic sugar; the use of
|
||||
/// parens affects the region binding rules, so we preserve the
|
||||
/// 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.
|
||||
|
@ -174,79 +177,8 @@ pub enum PathParameters {
|
|||
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>`
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Default)]
|
||||
pub struct AngleBracketedParameterData {
|
||||
/// The lifetime parameters for this path segment.
|
||||
pub lifetimes: Vec<Lifetime>,
|
||||
|
@ -258,9 +190,10 @@ pub struct AngleBracketedParameterData {
|
|||
pub bindings: P<[TypeBinding]>,
|
||||
}
|
||||
|
||||
impl AngleBracketedParameterData {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty()
|
||||
impl Into<Option<P<PathParameters>>> for AngleBracketedParameterData {
|
||||
fn into(self) -> Option<P<PathParameters>> {
|
||||
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> )
|
||||
-> ast::Path {
|
||||
let last_identifier = idents.pop().unwrap();
|
||||
let mut segments: Vec<ast::PathSegment> = idents.into_iter()
|
||||
.map(|ident| {
|
||||
ast::PathSegment {
|
||||
identifier: ident,
|
||||
parameters: ast::PathParameters::none(),
|
||||
}
|
||||
}).collect();
|
||||
segments.push(ast::PathSegment {
|
||||
identifier: last_identifier,
|
||||
parameters: ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
|
||||
let mut segments: Vec<ast::PathSegment> = idents.into_iter().map(Into::into).collect();
|
||||
let parameters = if lifetimes.is_empty() && types.is_empty() && bindings.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(P(ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
|
||||
lifetimes: lifetimes,
|
||||
types: P::from_vec(types),
|
||||
bindings: P::from_vec(bindings),
|
||||
})
|
||||
});
|
||||
})))
|
||||
};
|
||||
segments.push(ast::PathSegment { identifier: last_identifier, parameters: parameters });
|
||||
ast::Path {
|
||||
span: sp,
|
||||
global: global,
|
||||
|
@ -367,13 +363,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
|||
bindings: Vec<ast::TypeBinding>)
|
||||
-> (ast::QSelf, ast::Path) {
|
||||
let mut path = trait_path;
|
||||
path.segments.push(ast::PathSegment {
|
||||
identifier: ident,
|
||||
parameters: ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
|
||||
let parameters = ast::AngleBracketedParameterData {
|
||||
lifetimes: lifetimes,
|
||||
types: P::from_vec(types),
|
||||
bindings: P::from_vec(bindings),
|
||||
})
|
||||
};
|
||||
path.segments.push(ast::PathSegment {
|
||||
identifier: ident,
|
||||
parameters: Some(P(ast::PathParameters::AngleBracketed(parameters))),
|
||||
});
|
||||
|
||||
(ast::QSelf {
|
||||
|
|
|
@ -438,7 +438,7 @@ pub fn noop_fold_path<T: Folder>(Path {global, segments, span}: Path, fld: &mut
|
|||
global: global,
|
||||
segments: segments.move_map(|PathSegment {identifier, parameters}| PathSegment {
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -634,12 +634,7 @@ mod tests {
|
|||
node: ast::ExprKind::Path(None, ast::Path {
|
||||
span: sp(0, 1),
|
||||
global: false,
|
||||
segments: vec![
|
||||
ast::PathSegment {
|
||||
identifier: Ident::from_str("a"),
|
||||
parameters: ast::PathParameters::none(),
|
||||
}
|
||||
],
|
||||
segments: vec![Ident::from_str("a").into()],
|
||||
}),
|
||||
span: sp(0, 1),
|
||||
attrs: ThinVec::new(),
|
||||
|
@ -653,16 +648,7 @@ mod tests {
|
|||
node: ast::ExprKind::Path(None, ast::Path {
|
||||
span: sp(0, 6),
|
||||
global: true,
|
||||
segments: vec![
|
||||
ast::PathSegment {
|
||||
identifier: Ident::from_str("a"),
|
||||
parameters: ast::PathParameters::none(),
|
||||
},
|
||||
ast::PathSegment {
|
||||
identifier: Ident::from_str("b"),
|
||||
parameters: ast::PathParameters::none(),
|
||||
}
|
||||
]
|
||||
segments: vec![Ident::from_str("a").into(), Ident::from_str("b").into()],
|
||||
}),
|
||||
span: sp(0, 6),
|
||||
attrs: ThinVec::new(),
|
||||
|
@ -772,12 +758,7 @@ mod tests {
|
|||
node:ast::ExprKind::Path(None, ast::Path{
|
||||
span: sp(7, 8),
|
||||
global: false,
|
||||
segments: vec![
|
||||
ast::PathSegment {
|
||||
identifier: Ident::from_str("d"),
|
||||
parameters: ast::PathParameters::none(),
|
||||
}
|
||||
],
|
||||
segments: vec![Ident::from_str("d").into()],
|
||||
}),
|
||||
span:sp(7,8),
|
||||
attrs: ThinVec::new(),
|
||||
|
@ -795,12 +776,7 @@ mod tests {
|
|||
node: ast::ExprKind::Path(None, ast::Path {
|
||||
span:sp(0,1),
|
||||
global:false,
|
||||
segments: vec![
|
||||
ast::PathSegment {
|
||||
identifier: Ident::from_str("b"),
|
||||
parameters: ast::PathParameters::none(),
|
||||
}
|
||||
],
|
||||
segments: vec![Ident::from_str("b").into()],
|
||||
}),
|
||||
span: sp(0,1),
|
||||
attrs: ThinVec::new()})),
|
||||
|
@ -842,12 +818,7 @@ mod tests {
|
|||
node: ast::TyKind::Path(None, ast::Path{
|
||||
span:sp(10,13),
|
||||
global:false,
|
||||
segments: vec![
|
||||
ast::PathSegment {
|
||||
identifier: Ident::from_str("i32"),
|
||||
parameters: ast::PathParameters::none(),
|
||||
}
|
||||
],
|
||||
segments: vec![Ident::from_str("i32").into()],
|
||||
}),
|
||||
span:sp(10,13)
|
||||
}),
|
||||
|
@ -890,13 +861,7 @@ mod tests {
|
|||
ast::Path{
|
||||
span:sp(17,18),
|
||||
global:false,
|
||||
segments: vec![
|
||||
ast::PathSegment {
|
||||
identifier: Ident::from_str("b"),
|
||||
parameters:
|
||||
ast::PathParameters::none(),
|
||||
}
|
||||
],
|
||||
segments: vec![Ident::from_str("b").into()],
|
||||
}),
|
||||
span: sp(17,18),
|
||||
attrs: ThinVec::new()})),
|
||||
|
|
|
@ -1705,12 +1705,11 @@ impl<'a> Parser<'a> {
|
|||
// Parse types, optionally.
|
||||
let parameters = if self.eat_lt() {
|
||||
let (lifetimes, types, bindings) = self.parse_generic_values_after_lt()?;
|
||||
|
||||
ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
|
||||
ast::AngleBracketedParameterData {
|
||||
lifetimes: lifetimes,
|
||||
types: P::from_vec(types),
|
||||
bindings: P::from_vec(bindings),
|
||||
})
|
||||
}.into()
|
||||
} else if self.eat(&token::OpenDelim(token::Paren)) {
|
||||
let lo = self.prev_span.lo;
|
||||
|
||||
|
@ -1727,18 +1726,17 @@ impl<'a> Parser<'a> {
|
|||
|
||||
let hi = self.prev_span.hi;
|
||||
|
||||
ast::PathParameters::Parenthesized(ast::ParenthesizedParameterData {
|
||||
Some(P(ast::PathParameters::Parenthesized(ast::ParenthesizedParameterData {
|
||||
span: mk_sp(lo, hi),
|
||||
inputs: inputs,
|
||||
output: output_ty,
|
||||
})
|
||||
})))
|
||||
} else {
|
||||
ast::PathParameters::none()
|
||||
None
|
||||
};
|
||||
|
||||
// Assemble and push the result.
|
||||
segments.push(ast::PathSegment { identifier: identifier,
|
||||
parameters: parameters });
|
||||
segments.push(ast::PathSegment { identifier: identifier, parameters: parameters });
|
||||
|
||||
// Continue only if we see a `::`
|
||||
if !self.eat(&token::ModSep) {
|
||||
|
@ -1757,10 +1755,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
// If we do not see a `::`, stop.
|
||||
if !self.eat(&token::ModSep) {
|
||||
segments.push(ast::PathSegment {
|
||||
identifier: identifier,
|
||||
parameters: ast::PathParameters::none()
|
||||
});
|
||||
segments.push(identifier.into());
|
||||
return Ok(segments);
|
||||
}
|
||||
|
||||
|
@ -1768,14 +1763,13 @@ impl<'a> Parser<'a> {
|
|||
if self.eat_lt() {
|
||||
// Consumed `a::b::<`, go look for types
|
||||
let (lifetimes, types, bindings) = self.parse_generic_values_after_lt()?;
|
||||
let parameters = ast::AngleBracketedParameterData {
|
||||
segments.push(ast::PathSegment {
|
||||
identifier: identifier,
|
||||
parameters: ast::AngleBracketedParameterData {
|
||||
lifetimes: lifetimes,
|
||||
types: P::from_vec(types),
|
||||
bindings: P::from_vec(bindings),
|
||||
};
|
||||
segments.push(ast::PathSegment {
|
||||
identifier: identifier,
|
||||
parameters: ast::PathParameters::AngleBracketed(parameters),
|
||||
}.into(),
|
||||
});
|
||||
|
||||
// Consumed `a::b::<T,U>`, check for `::` before proceeding
|
||||
|
@ -1784,10 +1778,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
} else {
|
||||
// Consumed `a::`, go look for `b`
|
||||
segments.push(ast::PathSegment {
|
||||
identifier: identifier,
|
||||
parameters: ast::PathParameters::none(),
|
||||
});
|
||||
segments.push(identifier.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1802,10 +1793,7 @@ impl<'a> Parser<'a> {
|
|||
let identifier = self.parse_path_segment_ident()?;
|
||||
|
||||
// Assemble and push the result.
|
||||
segments.push(ast::PathSegment {
|
||||
identifier: identifier,
|
||||
parameters: ast::PathParameters::none()
|
||||
});
|
||||
segments.push(identifier.into());
|
||||
|
||||
// If we do not see a `::` or see `::{`/`::*`, stop.
|
||||
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_path_parameters(&segment.parameters, colons_before_params));
|
||||
if let Some(ref parameters) = segment.parameters {
|
||||
try!(self.print_path_parameters(parameters, colons_before_params))
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -2373,7 +2375,10 @@ impl<'a> State<'a> {
|
|||
try!(word(&mut self.s, "::"));
|
||||
let item_segment = path.segments.last().unwrap();
|
||||
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,
|
||||
|
@ -2381,10 +2386,6 @@ impl<'a> State<'a> {
|
|||
colons_before_params: bool)
|
||||
-> io::Result<()>
|
||||
{
|
||||
if parameters.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if colons_before_params {
|
||||
try!(word(&mut self.s, "::"))
|
||||
}
|
||||
|
|
|
@ -81,9 +81,8 @@ pub fn maybe_inject_crates_ref(sess: &ParseSess,
|
|||
vis: ast::Visibility::Inherited,
|
||||
node: ast::ItemKind::Use(P(codemap::dummy_spanned(ast::ViewPathGlob(ast::Path {
|
||||
global: false,
|
||||
segments: vec![name, "prelude", "v1"].into_iter().map(|name| ast::PathSegment {
|
||||
identifier: ast::Ident::from_str(name),
|
||||
parameters: ast::PathParameters::none(),
|
||||
segments: vec![name, "prelude", "v1"].into_iter().map(|name| {
|
||||
ast::Ident::from_str(name).into()
|
||||
}).collect(),
|
||||
span: span,
|
||||
})))),
|
||||
|
|
|
@ -580,10 +580,7 @@ fn path_node(ids: Vec<Ident>) -> ast::Path {
|
|||
ast::Path {
|
||||
span: DUMMY_SP,
|
||||
global: false,
|
||||
segments: ids.into_iter().map(|identifier| ast::PathSegment {
|
||||
identifier: identifier,
|
||||
parameters: ast::PathParameters::none(),
|
||||
}).collect()
|
||||
segments: ids.into_iter().map(Into::into).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -383,7 +383,9 @@ pub fn walk_path_segment<'a, V: Visitor<'a>>(visitor: &mut V,
|
|||
path_span: Span,
|
||||
segment: &'a PathSegment) {
|
||||
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,
|
||||
|
|
|
@ -59,14 +59,10 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
|
|||
|
||||
impl Result {
|
||||
fn path(&self) -> ast::Path {
|
||||
let segment = ast::PathSegment {
|
||||
identifier: self.ident,
|
||||
parameters: ast::PathParameters::none(),
|
||||
};
|
||||
ast::Path {
|
||||
span: self.span,
|
||||
global: false,
|
||||
segments: vec![segment],
|
||||
segments: vec![self.ident.into()],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue