From 954b5a81b46f60df640f36cfc83f04cd2a965051 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 20 Oct 2020 19:14:17 -0300 Subject: [PATCH 1/5] Rename parse_const_expr to parse_const_block --- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/mod.rs | 2 +- compiler/rustc_parse/src/parser/pat.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 698a7e7d9cde8..51ecc53ca261f 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1063,7 +1063,7 @@ impl<'a> Parser<'a> { } else if self.eat_keyword(kw::Unsafe) { self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided), attrs) } else if self.check_inline_const() { - self.parse_const_expr(lo.to(self.token.span)) + self.parse_const_block(lo.to(self.token.span)) } else if self.is_do_catch_block() { self.recover_do_catch(attrs) } else if self.is_try_block() { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index fb825256d92cd..4999498e4f73c 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -864,7 +864,7 @@ impl<'a> Parser<'a> { } /// Parses inline const expressions. - fn parse_const_expr(&mut self, span: Span) -> PResult<'a, P> { + fn parse_const_block(&mut self, span: Span) -> PResult<'a, P> { self.sess.gated_spans.gate(sym::inline_const, span); self.eat_keyword(kw::Const); let blk = self.parse_block()?; diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 15db2066a3053..356743f20713a 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -315,7 +315,7 @@ impl<'a> Parser<'a> { PatKind::Box(pat) } else if self.check_inline_const() { // Parse `const pat` - PatKind::Lit(self.parse_const_expr(lo.to(self.token.span))?) + PatKind::Lit(self.parse_const_block(lo.to(self.token.span))?) } else if self.can_be_ident_pat() { // Parse `ident @ pat` // This can give false positives and parse nullary enums, From f8842b9bacaf277430fa5c6cdf430b046dc7f323 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 19 Oct 2020 16:18:47 -0300 Subject: [PATCH 2/5] Make inline const work in range patterns --- compiler/rustc_parse/src/parser/pat.rs | 21 ++++++++++++----- .../ui/inline-const/const-match-pat-range.rs | 23 +++++++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/inline-const/const-match-pat-range.rs diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 356743f20713a..8da0a2f57d876 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -315,7 +315,13 @@ impl<'a> Parser<'a> { PatKind::Box(pat) } else if self.check_inline_const() { // Parse `const pat` - PatKind::Lit(self.parse_const_block(lo.to(self.token.span))?) + let const_expr = self.parse_const_block(lo.to(self.token.span))?; + + if let Some(re) = self.parse_range_end() { + self.parse_pat_range_begin_with(const_expr, re)? + } else { + PatKind::Lit(const_expr) + } } else if self.can_be_ident_pat() { // Parse `ident @ pat` // This can give false positives and parse nullary enums, @@ -716,17 +722,20 @@ impl<'a> Parser<'a> { } /// Is the token `dist` away from the current suitable as the start of a range patterns end? - fn is_pat_range_end_start(&self, dist: usize) -> bool { - self.look_ahead(dist, |t| { - t.is_path_start() // e.g. `MY_CONST`; + fn is_pat_range_end_start(&mut self, dist: usize) -> bool { + self.check_inline_const() + || self.look_ahead(dist, |t| { + t.is_path_start() // e.g. `MY_CONST`; || t.kind == token::Dot // e.g. `.5` for recovery; || t.can_begin_literal_maybe_minus() // e.g. `42`. || t.is_whole_expr() - }) + }) } fn parse_pat_range_end(&mut self) -> PResult<'a, P> { - if self.check_path() { + if self.check_inline_const() { + self.parse_const_block(self.token.span) + } else if self.check_path() { let lo = self.token.span; let (qself, path) = if self.eat_lt() { // Parse a qualified path diff --git a/src/test/ui/inline-const/const-match-pat-range.rs b/src/test/ui/inline-const/const-match-pat-range.rs new file mode 100644 index 0000000000000..4fbccfaf20064 --- /dev/null +++ b/src/test/ui/inline-const/const-match-pat-range.rs @@ -0,0 +1,23 @@ +// build-pass + +#![allow(incomplete_features)] +#![feature(inline_const)] +fn main() { + const N: u32 = 10; + let x: u32 = 3; + + match x { + const { N - 1 } ..= 10 => {}, + _ => {}, + } + + match x { + const { N - 1 } ..= const { N + 1 } => {}, + _ => {}, + } + + match x { + 1 ..= const { N + 1 } => {}, + _ => {}, + } +} From 83abed9df6ad0a8881270f166a02ffcaf437422f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 19 Oct 2020 18:44:37 -0300 Subject: [PATCH 3/5] Make inline const work for half open ranges --- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/mod.rs | 6 +++--- compiler/rustc_parse/src/parser/pat.rs | 8 ++++---- src/test/ui/inline-const/const-match-pat-range.rs | 12 +++++++++++- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 51ecc53ca261f..78c95428c7211 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1062,7 +1062,7 @@ impl<'a> Parser<'a> { }) } else if self.eat_keyword(kw::Unsafe) { self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided), attrs) - } else if self.check_inline_const() { + } else if self.check_inline_const(0) { self.parse_const_block(lo.to(self.token.span)) } else if self.is_do_catch_block() { self.recover_do_catch(attrs) diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 4999498e4f73c..8ff97453c1414 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -522,9 +522,9 @@ impl<'a> Parser<'a> { self.check_or_expected(self.token.can_begin_const_arg(), TokenType::Const) } - fn check_inline_const(&mut self) -> bool { - self.check_keyword(kw::Const) - && self.look_ahead(1, |t| match t.kind { + fn check_inline_const(&self, dist: usize) -> bool { + self.is_keyword_ahead(dist, &[kw::Const]) + && self.look_ahead(dist + 1, |t| match t.kind { token::Interpolated(ref nt) => matches!(**nt, token::NtBlock(..)), token::OpenDelim(DelimToken::Brace) => true, _ => false, diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 8da0a2f57d876..27fe75a23b6a8 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -313,7 +313,7 @@ impl<'a> Parser<'a> { let pat = self.parse_pat_with_range_pat(false, None)?; self.sess.gated_spans.gate(sym::box_patterns, lo.to(self.prev_token.span)); PatKind::Box(pat) - } else if self.check_inline_const() { + } else if self.check_inline_const(0) { // Parse `const pat` let const_expr = self.parse_const_block(lo.to(self.token.span))?; @@ -722,8 +722,8 @@ impl<'a> Parser<'a> { } /// Is the token `dist` away from the current suitable as the start of a range patterns end? - fn is_pat_range_end_start(&mut self, dist: usize) -> bool { - self.check_inline_const() + fn is_pat_range_end_start(&self, dist: usize) -> bool { + self.check_inline_const(dist) || self.look_ahead(dist, |t| { t.is_path_start() // e.g. `MY_CONST`; || t.kind == token::Dot // e.g. `.5` for recovery; @@ -733,7 +733,7 @@ impl<'a> Parser<'a> { } fn parse_pat_range_end(&mut self) -> PResult<'a, P> { - if self.check_inline_const() { + if self.check_inline_const(0) { self.parse_const_block(self.token.span) } else if self.check_path() { let lo = self.token.span; diff --git a/src/test/ui/inline-const/const-match-pat-range.rs b/src/test/ui/inline-const/const-match-pat-range.rs index 4fbccfaf20064..c50c4f42848ec 100644 --- a/src/test/ui/inline-const/const-match-pat-range.rs +++ b/src/test/ui/inline-const/const-match-pat-range.rs @@ -1,7 +1,7 @@ // build-pass #![allow(incomplete_features)] -#![feature(inline_const)] +#![feature(inline_const, half_open_range_patterns, exclusive_range_pattern)] fn main() { const N: u32 = 10; let x: u32 = 3; @@ -20,4 +20,14 @@ fn main() { 1 ..= const { N + 1 } => {}, _ => {}, } + + match x { + .. const { N + 1 } => {}, + _ => {}, + } + + match x { + const { N - 1 } .. => {}, + _ => {}, + } } From 5bef429dacb216b45a6bfa4c020d108c1d8e726e Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 20 Oct 2020 18:53:13 -0300 Subject: [PATCH 4/5] Add ..= const { .. } missing tests and sort them properly --- src/test/ui/inline-const/const-match-pat-range.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/test/ui/inline-const/const-match-pat-range.rs b/src/test/ui/inline-const/const-match-pat-range.rs index c50c4f42848ec..eefe43a1a2297 100644 --- a/src/test/ui/inline-const/const-match-pat-range.rs +++ b/src/test/ui/inline-const/const-match-pat-range.rs @@ -7,17 +7,17 @@ fn main() { let x: u32 = 3; match x { - const { N - 1 } ..= 10 => {}, + 1 ..= const { N + 1 } => {}, _ => {}, } match x { - const { N - 1 } ..= const { N + 1 } => {}, + const { N - 1 } ..= 10 => {}, _ => {}, } match x { - 1 ..= const { N + 1 } => {}, + const { N - 1 } ..= const { N + 1 } => {}, _ => {}, } @@ -30,4 +30,9 @@ fn main() { const { N - 1 } .. => {}, _ => {}, } + + match x { + ..= const { N + 1 } => {}, + _ => {} + } } From 5656a4151e07651df154911672055260f51614fd Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 20 Oct 2020 19:59:22 -0300 Subject: [PATCH 5/5] Bless tests --- src/test/ui/parser/issue-66357-unexpected-unreachable.rs | 2 +- src/test/ui/parser/issue-66357-unexpected-unreachable.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/parser/issue-66357-unexpected-unreachable.rs b/src/test/ui/parser/issue-66357-unexpected-unreachable.rs index 7b95bc775ba91..5ec143fae2344 100644 --- a/src/test/ui/parser/issue-66357-unexpected-unreachable.rs +++ b/src/test/ui/parser/issue-66357-unexpected-unreachable.rs @@ -13,4 +13,4 @@ fn f() { |[](* } //~^ ERROR expected one of `,` or `:`, found `(` -//~| ERROR expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `const`, `mut`, `ref`, `|`, identifier, or path, found `*` +//~| ERROR expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*` diff --git a/src/test/ui/parser/issue-66357-unexpected-unreachable.stderr b/src/test/ui/parser/issue-66357-unexpected-unreachable.stderr index 5549f73920d4f..c3810999d2395 100644 --- a/src/test/ui/parser/issue-66357-unexpected-unreachable.stderr +++ b/src/test/ui/parser/issue-66357-unexpected-unreachable.stderr @@ -4,7 +4,7 @@ error: expected one of `,` or `:`, found `(` LL | fn f() { |[](* } | ^ expected one of `,` or `:` -error: expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `const`, `mut`, `ref`, `|`, identifier, or path, found `*` +error: expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*` --> $DIR/issue-66357-unexpected-unreachable.rs:14:14 | LL | fn f() { |[](* }