diff options
| author | bors <bors@rust-lang.org> | 2015-05-12 13:04:14 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-05-12 13:04:14 +0000 |
| commit | 0ad202671fc031ee90133fa5849ef0ec31164e04 (patch) | |
| tree | af36d232f138a45b160a67a6bc762059ea7b3619 /src/libsyntax | |
| parent | 67dfc177f3c3236a73c7273dd0bf8be80bf1f5b0 (diff) | |
| parent | efb3872a49df2d4ffe5bdc948d1d12637fa3ebd1 (diff) | |
| download | rust-0ad202671fc031ee90133fa5849ef0ec31164e04.tar.gz rust-0ad202671fc031ee90133fa5849ef0ec31164e04.zip | |
Auto merge of #25171 - quantheory:associated_time_long_paths, r=nikomatsakis
It is currently broken to use syntax such as `<T as Foo>::U::static_method()` where `<T as Foo>::U` is an associated type. I was able to fix this and simplify the parser a bit at the same time. This also fixes the corresponding issue with associated types (#22139), but that's somewhat irrelevant because #22519 is still open, so this syntax still causes an error in type checking. Similarly, although this fix applies to associated consts, #25046 forbids associated constants from using type parameters or `Self`, while #19559 means that associated types have to always have one of those two. Therefore, I think that you can't use an associated const from an associated type anyway.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 50 |
1 files changed, 15 insertions, 35 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index eb1c338ac85..541ec16b415 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -109,15 +109,6 @@ pub enum PathParsingMode { LifetimeAndTypesWithColons, } -/// How to parse a qualified path, whether to allow trailing parameters. -#[derive(Copy, Clone, PartialEq)] -pub enum QPathParsingMode { - /// No trailing parameters, e.g. `<T as Trait>::Item` - NoParameters, - /// Optional parameters, e.g. `<T as Trait>::item::<'a, U>` - MaybeParameters, -} - /// How to parse a bound, whether to allow bound modifiers such as `?`. #[derive(Copy, Clone, PartialEq)] pub enum BoundParsingMode { @@ -1359,7 +1350,7 @@ impl<'a> Parser<'a> { } else if try!(self.eat_lt()) { let (qself, path) = - try!(self.parse_qualified_path(QPathParsingMode::NoParameters)); + try!(self.parse_qualified_path(NoTypesAllowed)); TyPath(Some(qself), path) } else if self.check(&token::ModSep) || @@ -1578,7 +1569,7 @@ impl<'a> Parser<'a> { // QUALIFIED PATH `<TYPE [as TRAIT_REF]>::IDENT[::<PARAMS>]` // Assumes that the leading `<` has been parsed already. - pub fn parse_qualified_path(&mut self, mode: QPathParsingMode) + pub fn parse_qualified_path(&mut self, mode: PathParsingMode) -> PResult<(QSelf, ast::Path)> { let self_type = try!(self.parse_ty_sum()); let mut path = if try!(self.eat_keyword(keywords::As)) { @@ -1599,29 +1590,18 @@ impl<'a> Parser<'a> { try!(self.expect(&token::Gt)); try!(self.expect(&token::ModSep)); - let item_name = try!(self.parse_ident()); - let parameters = match mode { - QPathParsingMode::NoParameters => ast::PathParameters::none(), - QPathParsingMode::MaybeParameters => { - if try!(self.eat(&token::ModSep)) { - try!(self.expect_lt()); - // Consumed `item::<`, go look for types - let (lifetimes, types, bindings) = - try!(self.parse_generic_values_after_lt()); - ast::AngleBracketedParameters(ast::AngleBracketedParameterData { - lifetimes: lifetimes, - types: OwnedSlice::from_vec(types), - bindings: OwnedSlice::from_vec(bindings), - }) - } else { - ast::PathParameters::none() - } + let segments = match mode { + LifetimeAndTypesWithoutColons => { + try!(self.parse_path_segments_without_colons()) + } + LifetimeAndTypesWithColons => { + try!(self.parse_path_segments_with_colons()) + } + NoTypesAllowed => { + try!(self.parse_path_segments_without_types()) } }; - path.segments.push(ast::PathSegment { - identifier: item_name, - parameters: parameters - }); + path.segments.extend(segments); if path.segments.len() == 1 { path.span.lo = self.last_span.lo; @@ -2096,7 +2076,7 @@ impl<'a> Parser<'a> { if try!(self.eat_lt()){ let (qself, path) = - try!(self.parse_qualified_path(QPathParsingMode::MaybeParameters)); + try!(self.parse_qualified_path(LifetimeAndTypesWithColons)); return Ok(self.mk_expr(lo, hi, ExprPath(Some(qself), path))); } @@ -3176,7 +3156,7 @@ impl<'a> Parser<'a> { let (qself, path) = if try!(self.eat_lt()) { // Parse a qualified path let (qself, path) = - try!(self.parse_qualified_path(QPathParsingMode::NoParameters)); + try!(self.parse_qualified_path(NoTypesAllowed)); (Some(qself), path) } else { // Parse an unqualified path @@ -3270,7 +3250,7 @@ impl<'a> Parser<'a> { let (qself, path) = if try!(self.eat_lt()) { // Parse a qualified path let (qself, path) = - try!(self.parse_qualified_path(QPathParsingMode::NoParameters)); + try!(self.parse_qualified_path(NoTypesAllowed)); (Some(qself), path) } else { // Parse an unqualified path |
