diff options
| author | Michael Goulet <michael@errs.io> | 2024-07-10 18:06:44 -0400 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2024-07-11 00:00:03 -0400 |
| commit | de88bc5c8921774681ecac0a5249b370a9768a6c (patch) | |
| tree | d22d79947a9547d7b867fd23b74f36581e23d34c /compiler/rustc_parse/src | |
| parent | 898ed2ffa6c485530af1fbe6117c0deb4290715f (diff) | |
| download | rust-de88bc5c8921774681ecac0a5249b370a9768a6c.tar.gz rust-de88bc5c8921774681ecac0a5249b370a9768a6c.zip | |
And additionally enforce ? and async/const aren't mixed
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/errors.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/ty.rs | 29 |
2 files changed, 40 insertions, 0 deletions
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 9b18a771fde..75417885d2a 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -3060,3 +3060,14 @@ pub struct BinderAndPolarity { pub binder_span: Span, pub polarity: &'static str, } + +#[derive(Diagnostic)] +#[diag(parse_modifiers_and_polarity)] +pub struct PolarityAndModifiers { + #[primary_span] + pub polarity_span: Span, + #[label] + pub modifiers_span: Span, + pub polarity: &'static str, + pub modifiers_concatenated: String, +} diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 6de778fa9f2..a2db4b6feef 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -930,6 +930,7 @@ impl<'a> Parser<'a> { /// TRAIT_BOUND_MODIFIERS = [["~"] "const"] ["async"] ["?" | "!"] /// ``` fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> { + let modifier_lo = self.token.span; let constness = if self.eat(&token::Tilde) { let tilde = self.prev_token.span; self.expect_keyword(kw::Const)?; @@ -962,6 +963,7 @@ impl<'a> Parser<'a> { } else { BoundAsyncness::Normal }; + let modifier_hi = self.prev_token.span; let polarity = if self.eat(&token::Question) { BoundPolarity::Maybe(self.prev_token.span) @@ -972,6 +974,33 @@ impl<'a> Parser<'a> { BoundPolarity::Positive }; + // Enforce the mutual-exclusivity of `const`/`async` and `?`/`!`. + match polarity { + BoundPolarity::Positive => { + // All trait bound modifiers allowed to combine with positive polarity + } + BoundPolarity::Maybe(polarity_span) | BoundPolarity::Negative(polarity_span) => { + match (asyncness, constness) { + (BoundAsyncness::Normal, BoundConstness::Never) => { + // Ok, no modifiers. + } + (_, _) => { + let constness = constness.as_str(); + let asyncness = asyncness.as_str(); + let glue = + if !constness.is_empty() && !asyncness.is_empty() { " " } else { "" }; + let modifiers_concatenated = format!("{constness}{glue}{asyncness}"); + self.dcx().emit_err(errors::PolarityAndModifiers { + polarity_span, + polarity: polarity.as_str(), + modifiers_span: modifier_lo.to(modifier_hi), + modifiers_concatenated, + }); + } + } + } + } + Ok(TraitBoundModifiers { constness, asyncness, polarity }) } |
