Fix issue with single question mark or paren
This commit is contained in:
parent
e038f58105
commit
6e75def7db
3 changed files with 44 additions and 25 deletions
|
@ -781,10 +781,11 @@ never_type : "!" ;
|
||||||
### Type parameter bounds
|
### Type parameter bounds
|
||||||
|
|
||||||
```antlr
|
```antlr
|
||||||
|
bound-list := bound | bound '+' bound-list '+' ?
|
||||||
bound := ty_bound | lt_bound
|
bound := ty_bound | lt_bound
|
||||||
lt_bound := lifetime
|
lt_bound := lifetime
|
||||||
ty_bound := [?] [ for<lt_param_defs> ] simple_path
|
ty_bound := ty_bound_noparen | (ty_bound_noparen)
|
||||||
bound-list := bound | bound '+' bound-list '+' ?
|
ty_bound_noparen := [?] [ for<lt_param_defs> ] simple_path
|
||||||
```
|
```
|
||||||
|
|
||||||
### Self types
|
### Self types
|
||||||
|
|
|
@ -4086,20 +4086,20 @@ impl<'a> Parser<'a> {
|
||||||
fn parse_ty_param_bounds_common(&mut self, allow_plus: bool) -> PResult<'a, TyParamBounds> {
|
fn parse_ty_param_bounds_common(&mut self, allow_plus: bool) -> PResult<'a, TyParamBounds> {
|
||||||
let mut bounds = Vec::new();
|
let mut bounds = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
|
let is_bound_start = self.check_path() || self.check_lifetime() ||
|
||||||
|
self.check(&token::Question) ||
|
||||||
|
self.check_keyword(keywords::For) ||
|
||||||
|
self.check(&token::OpenDelim(token::Paren));
|
||||||
|
if is_bound_start {
|
||||||
let has_parens = self.eat(&token::OpenDelim(token::Paren));
|
let has_parens = self.eat(&token::OpenDelim(token::Paren));
|
||||||
let question = if self.eat(&token::Question) { Some(self.prev_span) } else { None };
|
let question = if self.eat(&token::Question) { Some(self.prev_span) } else { None };
|
||||||
if self.check_lifetime() {
|
if self.token.is_lifetime() {
|
||||||
if let Some(question_span) = question {
|
if let Some(question_span) = question {
|
||||||
self.span_err(question_span,
|
self.span_err(question_span,
|
||||||
"`?` may only modify trait bounds, not lifetime bounds");
|
"`?` may only modify trait bounds, not lifetime bounds");
|
||||||
}
|
}
|
||||||
bounds.push(RegionTyParamBound(self.expect_lifetime()));
|
bounds.push(RegionTyParamBound(self.expect_lifetime()));
|
||||||
if has_parens {
|
} else {
|
||||||
self.expect(&token::CloseDelim(token::Paren))?;
|
|
||||||
self.span_err(self.prev_span,
|
|
||||||
"parenthesized lifetime bounds are not supported");
|
|
||||||
}
|
|
||||||
} else if self.check_keyword(keywords::For) || self.check_path() {
|
|
||||||
let lo = self.span;
|
let lo = self.span;
|
||||||
let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
|
let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
|
||||||
let path = self.parse_path(PathStyle::Type)?;
|
let path = self.parse_path(PathStyle::Type)?;
|
||||||
|
@ -4110,8 +4110,13 @@ impl<'a> Parser<'a> {
|
||||||
TraitBoundModifier::None
|
TraitBoundModifier::None
|
||||||
};
|
};
|
||||||
bounds.push(TraitTyParamBound(poly_trait, modifier));
|
bounds.push(TraitTyParamBound(poly_trait, modifier));
|
||||||
|
}
|
||||||
if has_parens {
|
if has_parens {
|
||||||
self.expect(&token::CloseDelim(token::Paren))?;
|
self.expect(&token::CloseDelim(token::Paren))?;
|
||||||
|
if let Some(&RegionTyParamBound(..)) = bounds.last() {
|
||||||
|
self.span_err(self.prev_span,
|
||||||
|
"parenthesized lifetime bounds are not supported");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
|
|
13
src/test/parse-fail/bound-single-question-mark.rs
Normal file
13
src/test/parse-fail/bound-single-question-mark.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// compile-flags: -Z parse-only
|
||||||
|
|
||||||
|
fn f<T: ?>() {} //~ ERROR expected identifier, found `>`
|
Loading…
Add table
Add a link
Reference in a new issue