diff options
| author | bors <bors@rust-lang.org> | 2020-03-11 13:05:52 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-03-11 13:05:52 +0000 |
| commit | c20d7eecbc0928b57da8fe30b2ef8528e2bdd5be (patch) | |
| tree | e8f110a9249dbcf8ce290bda1b3c7702488247fa /src/librustc_parse/parser/ty.rs | |
| parent | 303d8aff6092709edd4dbd35b1c88e9aa40bf6d8 (diff) | |
| parent | a77206fa4a35e7926fb4404bd167b06e342b7626 (diff) | |
Auto merge of #69919 - Centril:rollup-fxo33zs, r=Centril
Rollup of 8 pull requests Successful merges: - #66472 (--show-coverage json) - #69603 (tidy: replace `make check` with `./x.py test` in documentation) - #69760 (Improve expression & attribute parsing) - #69828 (fix memory leak when vec::IntoIter panics during drop) - #69850 (panic_bounds_check: use caller_location, like PanicFnLangItem) - #69876 (Add long error explanation for E0739) - #69888 ([Miri] Use a session variable instead of checking for an env var always) - #69893 (librustc_codegen_llvm: Use slices instead of 0-terminated strings) Failed merges: r? @ghost
Diffstat (limited to 'src/librustc_parse/parser/ty.rs')
| -rw-r--r-- | src/librustc_parse/parser/ty.rs | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index 16adf5c05a4..3dd415bf372 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -142,24 +142,20 @@ impl<'a> Parser<'a> { } else { let path = self.parse_path(PathStyle::Type)?; let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus(); - self.parse_remaining_bounds(lifetime_defs, path, lo, parse_plus)? + self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)? } } else if self.eat_keyword(kw::Impl) { self.parse_impl_ty(&mut impl_dyn_multi)? } else if self.is_explicit_dyn_type() { self.parse_dyn_ty(&mut impl_dyn_multi)? - } else if self.check(&token::Question) - || self.check_lifetime() && self.look_ahead(1, |t| t.is_like_plus()) - { - // Bound list (trait object type) - let bounds = self.parse_generic_bounds_common(allow_plus, None)?; - TyKind::TraitObject(bounds, TraitObjectSyntax::None) } else if self.eat_lt() { // Qualified path let (qself, path) = self.parse_qpath(PathStyle::Type)?; TyKind::Path(Some(qself), path) - } else if self.token.is_path_start() { + } else if self.check_path() { self.parse_path_start_ty(lo, allow_plus)? + } else if self.can_begin_bound() { + self.parse_bare_trait_object(lo, allow_plus)? } else if self.eat(&token::DotDotDot) { if allow_c_variadic == AllowCVariadic::Yes { TyKind::CVarArgs @@ -203,21 +199,12 @@ impl<'a> Parser<'a> { match ty.kind { // `(TY_BOUND_NOPAREN) + BOUND + ...`. TyKind::Path(None, path) if maybe_bounds => { - self.parse_remaining_bounds(Vec::new(), path, lo, true) + self.parse_remaining_bounds_path(Vec::new(), path, lo, true) } - TyKind::TraitObject(mut bounds, TraitObjectSyntax::None) + TyKind::TraitObject(bounds, TraitObjectSyntax::None) if maybe_bounds && bounds.len() == 1 && !trailing_plus => { - let path = match bounds.remove(0) { - GenericBound::Trait(pt, ..) => pt.trait_ref.path, - GenericBound::Outlives(..) => { - return Err(self.struct_span_err( - ty.span, - "expected trait bound, not lifetime bound", - )); - } - }; - self.parse_remaining_bounds(Vec::new(), path, lo, true) + self.parse_remaining_bounds(bounds, true) } // `(TYPE)` _ => Ok(TyKind::Paren(P(ty))), @@ -227,18 +214,35 @@ impl<'a> Parser<'a> { } } - fn parse_remaining_bounds( + fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> { + let lt_no_plus = self.check_lifetime() && !self.look_ahead(1, |t| t.is_like_plus()); + let bounds = self.parse_generic_bounds_common(allow_plus, None)?; + if lt_no_plus { + self.struct_span_err(lo, "lifetime in trait object type must be followed by `+`").emit() + } + Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None)) + } + + fn parse_remaining_bounds_path( &mut self, generic_params: Vec<GenericParam>, path: ast::Path, lo: Span, parse_plus: bool, ) -> PResult<'a, TyKind> { - assert_ne!(self.token, token::Question); - let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_token.span)); - let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)]; - if parse_plus { + let bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)]; + self.parse_remaining_bounds(bounds, parse_plus) + } + + /// Parse the remainder of a bare trait object type given an already parsed list. + fn parse_remaining_bounds( + &mut self, + mut bounds: GenericBounds, + plus: bool, + ) -> PResult<'a, TyKind> { + assert_ne!(self.token, token::Question); + if plus { self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded bounds.append(&mut self.parse_generic_bounds(Some(self.prev_token.span))?); } @@ -358,7 +362,7 @@ impl<'a> Parser<'a> { })) } else if allow_plus == AllowPlus::Yes && self.check_plus() { // `Trait1 + Trait2 + 'a` - self.parse_remaining_bounds(Vec::new(), path, lo, true) + self.parse_remaining_bounds_path(Vec::new(), path, lo, true) } else { // Just a type path. Ok(TyKind::Path(None, path)) |
