Support parenthesized paths Foo(A,B) -> C
that expand to Foo<(A,B),C>
. These paths also bind anonymous regions (or will, once HRTB is fully working).
Fixes #18423.
This commit is contained in:
parent
4e352892c8
commit
221edbae38
38 changed files with 841 additions and 264 deletions
|
@ -1487,9 +1487,9 @@ impl<'a> Parser<'a> {
|
|||
trait_name: trait_name.path,
|
||||
item_name: item_name,
|
||||
}))
|
||||
} else if self.token == token::ModSep
|
||||
|| self.token.is_ident()
|
||||
|| self.token.is_path() {
|
||||
} else if self.token == token::ModSep ||
|
||||
self.token.is_ident() ||
|
||||
self.token.is_path() {
|
||||
// NAMED TYPE
|
||||
let mode = if plus_allowed {
|
||||
LifetimeAndTypesAndBounds
|
||||
|
@ -1771,27 +1771,36 @@ impl<'a> Parser<'a> {
|
|||
let identifier = self.parse_ident();
|
||||
|
||||
// Parse types, optionally.
|
||||
let (lifetimes, types) = if self.eat_lt(false) {
|
||||
self.parse_generic_values_after_lt()
|
||||
} else if false && self.eat(&token::LParen) {
|
||||
let mut types = self.parse_seq_to_end(
|
||||
&token::RParen,
|
||||
let parameters = if self.eat_lt(false) {
|
||||
let (lifetimes, types) = self.parse_generic_values_after_lt();
|
||||
|
||||
ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
|
||||
lifetimes: lifetimes,
|
||||
types: OwnedSlice::from_vec(types),
|
||||
})
|
||||
} else if self.eat(&token::OpenDelim(token::Paren)) {
|
||||
let inputs = self.parse_seq_to_end(
|
||||
&token::CloseDelim(token::Paren),
|
||||
seq_sep_trailing_allowed(token::Comma),
|
||||
|p| p.parse_ty(true));
|
||||
|
||||
if self.eat(&token::RArrow) {
|
||||
types.push(self.parse_ty(true))
|
||||
}
|
||||
let output_ty = if self.eat(&token::RArrow) {
|
||||
Some(self.parse_ty(true))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
(Vec::new(), types)
|
||||
ast::ParenthesizedParameters(ast::ParenthesizedParameterData {
|
||||
inputs: inputs,
|
||||
output: output_ty
|
||||
})
|
||||
} else {
|
||||
(Vec::new(), Vec::new())
|
||||
ast::PathParameters::none()
|
||||
};
|
||||
|
||||
// Assemble and push the result.
|
||||
segments.push(ast::PathSegment { identifier: identifier,
|
||||
lifetimes: lifetimes,
|
||||
types: OwnedSlice::from_vec(types), });
|
||||
parameters: parameters });
|
||||
|
||||
// Continue only if we see a `::`
|
||||
if !self.eat(&token::ModSep) {
|
||||
|
@ -1810,9 +1819,13 @@ impl<'a> Parser<'a> {
|
|||
|
||||
// If we do not see a `::`, stop.
|
||||
if !self.eat(&token::ModSep) {
|
||||
segments.push(ast::PathSegment { identifier: identifier,
|
||||
lifetimes: Vec::new(),
|
||||
types: OwnedSlice::empty() });
|
||||
segments.push(ast::PathSegment {
|
||||
identifier: identifier,
|
||||
parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
|
||||
lifetimes: Vec::new(),
|
||||
types: OwnedSlice::empty(),
|
||||
})
|
||||
});
|
||||
return segments;
|
||||
}
|
||||
|
||||
|
@ -1820,9 +1833,13 @@ impl<'a> Parser<'a> {
|
|||
if self.eat_lt(false) {
|
||||
// Consumed `a::b::<`, go look for types
|
||||
let (lifetimes, types) = self.parse_generic_values_after_lt();
|
||||
segments.push(ast::PathSegment { identifier: identifier,
|
||||
lifetimes: lifetimes,
|
||||
types: OwnedSlice::from_vec(types) });
|
||||
segments.push(ast::PathSegment {
|
||||
identifier: identifier,
|
||||
parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
|
||||
lifetimes: lifetimes,
|
||||
types: OwnedSlice::from_vec(types),
|
||||
}),
|
||||
});
|
||||
|
||||
// Consumed `a::b::<T,U>`, check for `::` before proceeding
|
||||
if !self.eat(&token::ModSep) {
|
||||
|
@ -1830,9 +1847,10 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
} else {
|
||||
// Consumed `a::`, go look for `b`
|
||||
segments.push(ast::PathSegment { identifier: identifier,
|
||||
lifetimes: Vec::new(),
|
||||
types: OwnedSlice::empty() });
|
||||
segments.push(ast::PathSegment {
|
||||
identifier: identifier,
|
||||
parameters: ast::PathParameters::none(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1847,9 +1865,10 @@ impl<'a> Parser<'a> {
|
|||
let identifier = self.parse_ident();
|
||||
|
||||
// Assemble and push the result.
|
||||
segments.push(ast::PathSegment { identifier: identifier,
|
||||
lifetimes: Vec::new(),
|
||||
types: OwnedSlice::empty(), });
|
||||
segments.push(ast::PathSegment {
|
||||
identifier: identifier,
|
||||
parameters: ast::PathParameters::none()
|
||||
});
|
||||
|
||||
// If we do not see a `::`, stop.
|
||||
if !self.eat(&token::ModSep) {
|
||||
|
@ -3455,13 +3474,9 @@ impl<'a> Parser<'a> {
|
|||
},
|
||||
_ => {
|
||||
if !enum_path.global &&
|
||||
enum_path.segments.len() == 1 &&
|
||||
enum_path.segments[0]
|
||||
.lifetimes
|
||||
.len() == 0 &&
|
||||
enum_path.segments[0]
|
||||
.types
|
||||
.len() == 0 {
|
||||
enum_path.segments.len() == 1 &&
|
||||
enum_path.segments[0].parameters.is_empty()
|
||||
{
|
||||
// it could still be either an enum
|
||||
// or an identifier pattern, resolve
|
||||
// will sort it out:
|
||||
|
@ -3960,8 +3975,7 @@ impl<'a> Parser<'a> {
|
|||
fn trait_ref_from_ident(ident: Ident, span: Span) -> ast::TraitRef {
|
||||
let segment = ast::PathSegment {
|
||||
identifier: ident,
|
||||
lifetimes: Vec::new(),
|
||||
types: OwnedSlice::empty(),
|
||||
parameters: ast::PathParameters::none()
|
||||
};
|
||||
let path = ast::Path {
|
||||
span: span,
|
||||
|
@ -5677,8 +5691,7 @@ impl<'a> Parser<'a> {
|
|||
segments: path.into_iter().map(|identifier| {
|
||||
ast::PathSegment {
|
||||
identifier: identifier,
|
||||
lifetimes: Vec::new(),
|
||||
types: OwnedSlice::empty(),
|
||||
parameters: ast::PathParameters::none(),
|
||||
}
|
||||
}).collect()
|
||||
};
|
||||
|
@ -5712,8 +5725,7 @@ impl<'a> Parser<'a> {
|
|||
segments: path.into_iter().map(|identifier| {
|
||||
ast::PathSegment {
|
||||
identifier: identifier,
|
||||
lifetimes: Vec::new(),
|
||||
types: OwnedSlice::empty(),
|
||||
parameters: ast::PathParameters::none(),
|
||||
}
|
||||
}).collect()
|
||||
};
|
||||
|
@ -5730,8 +5742,7 @@ impl<'a> Parser<'a> {
|
|||
segments: path.into_iter().map(|identifier| {
|
||||
ast::PathSegment {
|
||||
identifier: identifier,
|
||||
lifetimes: Vec::new(),
|
||||
types: OwnedSlice::empty(),
|
||||
parameters: ast::PathParameters::none(),
|
||||
}
|
||||
}).collect()
|
||||
};
|
||||
|
@ -5752,8 +5763,7 @@ impl<'a> Parser<'a> {
|
|||
segments: path.into_iter().map(|identifier| {
|
||||
ast::PathSegment {
|
||||
identifier: identifier,
|
||||
lifetimes: Vec::new(),
|
||||
types: OwnedSlice::empty(),
|
||||
parameters: ast::PathParameters::none(),
|
||||
}
|
||||
}).collect()
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue