diff options
| author | bors <bors@rust-lang.org> | 2024-06-18 09:30:38 +0000 | 
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-06-18 09:30:38 +0000 | 
| commit | c1f62a7c35349438ea9728abbe1bcf1cebd426b7 (patch) | |
| tree | 257f509fbdc6f8439505426b2f899b46960f662b /compiler/rustc_parse/src/parser/ty.rs | |
| parent | f873ae029e3ee2bbb8bc70a7ef3f1a06c22b0eac (diff) | |
| parent | 227374714f3429e401c2c572a7eba00a4423ae09 (diff) | |
| download | rust-c1f62a7c35349438ea9728abbe1bcf1cebd426b7.tar.gz rust-c1f62a7c35349438ea9728abbe1bcf1cebd426b7.zip | |
Auto merge of #126049 - compiler-errors:rework-use, r=oli-obk
Rework `feature(precise_capturing)` to represent `use<...>` as a syntactical bound Reworks `precise_capturing` for a recent lang-team consensus. Specifically: > The conclusion of the team is that we'll make use<..> a bound. That is, we'll support impl use<..> + Trait, impl Trait + use<..>, etc. > For now, we will support at most one such bound in a list of bounds, and semantically we'll only support these bounds in the item bounds of RPIT-like impl Trait opaque types (i.e., in the places discussed in the RFC). Lang decision in favor of this approach: - https://github.com/rust-lang/rust/issues/125836#issuecomment-2151351849 Tracking: - https://github.com/rust-lang/rust/issues/123432
Diffstat (limited to 'compiler/rustc_parse/src/parser/ty.rs')
| -rw-r--r-- | compiler/rustc_parse/src/parser/ty.rs | 41 | 
1 files changed, 22 insertions, 19 deletions
| diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 5bed0317e5e..fcd623b477f 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -9,7 +9,7 @@ use crate::errors::{ use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; use rustc_ast::ptr::P; -use rustc_ast::token::{self, Delimiter, Token, TokenKind}; +use rustc_ast::token::{self, BinOpToken, Delimiter, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::{ self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, FnRetTy, GenericBound, @@ -316,7 +316,7 @@ impl<'a> Parser<'a> { TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn) } (TyKind::TraitObject(bounds, _), kw::Impl) => { - TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds, None) + TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds) } _ => return Err(err), }; @@ -670,33 +670,26 @@ impl<'a> Parser<'a> { }) } - // parse precise captures, if any. This is `use<'lt, 'lt, P, P>`; a list of - // lifetimes and ident params (including SelfUpper). These are validated later - // for order, duplication, and whether they actually reference params. - let precise_capturing = if self.eat_keyword(kw::Use) { - let use_span = self.prev_token.span; - self.psess.gated_spans.gate(sym::precise_capturing, use_span); - let (args, args_span) = self.parse_precise_capturing_args()?; - Some(P((args, use_span.to(args_span)))) - } else { - None - }; - // Always parse bounds greedily for better error recovery. let bounds = self.parse_generic_bounds()?; *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus); - Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds, precise_capturing)) + Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)) } fn parse_precise_capturing_args( &mut self, ) -> PResult<'a, (ThinVec<PreciseCapturingArg>, Span)> { let lo = self.token.span; - let (args, _) = self.parse_unspanned_seq( - &TokenKind::Lt, - &TokenKind::Gt, + self.expect_lt()?; + let (args, _, _) = self.parse_seq_to_before_tokens( + &[&TokenKind::Gt], + &[ + &TokenKind::Ge, + &TokenKind::BinOp(BinOpToken::Shr), + &TokenKind::BinOpEq(BinOpToken::Shr), + ], SeqSep::trailing_allowed(token::Comma), |self_| { if self_.check_keyword(kw::SelfUpper) { @@ -717,6 +710,7 @@ impl<'a> Parser<'a> { } }, )?; + self.expect_gt()?; Ok((args, lo.to(self.prev_token.span))) } @@ -828,6 +822,7 @@ impl<'a> Parser<'a> { || self.check(&token::OpenDelim(Delimiter::Parenthesis)) || self.check_keyword(kw::Const) || self.check_keyword(kw::Async) + || self.check_keyword(kw::Use) } /// Parses a bound according to the grammar: @@ -844,6 +839,14 @@ impl<'a> Parser<'a> { let bound = if self.token.is_lifetime() { self.error_lt_bound_with_modifiers(modifiers); self.parse_generic_lt_bound(lo, inner_lo, has_parens)? + } else if self.eat_keyword(kw::Use) { + // parse precise captures, if any. This is `use<'lt, 'lt, P, P>`; a list of + // lifetimes and ident params (including SelfUpper). These are validated later + // for order, duplication, and whether they actually reference params. + let use_span = self.prev_token.span; + self.psess.gated_spans.gate(sym::precise_capturing, use_span); + let (args, args_span) = self.parse_precise_capturing_args()?; + GenericBound::Use(args, use_span.to(args_span)) } else { self.parse_generic_ty_bound(lo, has_parens, modifiers, &leading_token)? }; @@ -1003,7 +1006,7 @@ impl<'a> Parser<'a> { Applicability::MaybeIncorrect, ) } - TyKind::ImplTrait(_, bounds, None) + TyKind::ImplTrait(_, bounds) if let [GenericBound::Trait(tr, ..), ..] = bounds.as_slice() => { ( | 
