diff options
| author | Zack M. Davis <code@zackmdavis.net> | 2018-05-28 19:32:03 -0700 |
|---|---|---|
| committer | Zack M. Davis <code@zackmdavis.net> | 2018-06-26 07:54:49 -0700 |
| commit | 3fb76f4027596f524403e6eea60e9531e70e9460 (patch) | |
| tree | 7dd227fd8bf34166a93324df392ac057e2965b36 /src/libsyntax | |
| parent | 057715557b51af125847da6d19b2e016283c5ae7 (diff) | |
| download | rust-3fb76f4027596f524403e6eea60e9531e70e9460.tar.gz rust-3fb76f4027596f524403e6eea60e9531e70e9460.zip | |
inclusive range syntax lint (`...` → `..=`)
Our implementation ends up changing the `PatKind::Range` variant in the AST to take a `Spanned<RangeEnd>` instead of just a `RangeEnd`, because the alternative would be to try to infer the span of the range operator from the spans of the start and end subexpressions, which is both hideous and nontrivial to get right (whereas getting the change to the AST right was a simple game of type tennis). This is concerning #51043.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 33 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 4 |
5 files changed, 28 insertions, 18 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a09055e6c4a..53465c071f3 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -617,7 +617,7 @@ pub enum PatKind { /// A literal Lit(P<Expr>), /// A range pattern, e.g. `1...2`, `1..=2` or `1..2` - Range(P<Expr>, P<Expr>, RangeEnd), + Range(P<Expr>, P<Expr>, Spanned<RangeEnd>), /// `[a, b, ..i, y, z]` is represented as: /// `PatKind::Slice(box [a, b], Some(i), box [y, z])` Slice(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>), diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 51d7a236995..c813ec1977b 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -28,6 +28,7 @@ use self::AttributeGate::*; use rustc_target::spec::abi::Abi; use ast::{self, NodeId, PatKind, RangeEnd}; use attr; +use codemap::Spanned; use edition::{ALL_EDITIONS, Edition}; use syntax_pos::{Span, DUMMY_SP}; use errors::{DiagnosticBuilder, Handler, FatalError}; @@ -1752,7 +1753,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { pattern.span, "box pattern syntax is experimental"); } - PatKind::Range(_, _, RangeEnd::Excluded) => { + PatKind::Range(_, _, Spanned { node: RangeEnd::Excluded, .. }) => { gate_feature_post!(&self, exclusive_range_pattern, pattern.span, "exclusive range pattern syntax is experimental"); } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index ffea713f4ec..712d00fde32 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1137,10 +1137,10 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> { } PatKind::Box(inner) => PatKind::Box(folder.fold_pat(inner)), PatKind::Ref(inner, mutbl) => PatKind::Ref(folder.fold_pat(inner), mutbl), - PatKind::Range(e1, e2, end) => { + PatKind::Range(e1, e2, Spanned { span, node: end }) => { PatKind::Range(folder.fold_expr(e1), folder.fold_expr(e2), - folder.fold_range_end(end)) + Spanned { span, node: folder.fold_range_end(end) }) }, PatKind::Slice(before, slice, after) => { PatKind::Slice(before.move_map(|x| folder.fold_pat(x)), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 955bdbdcf91..21bd6c08324 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4024,12 +4024,14 @@ impl<'a> Parser<'a> { _ => panic!("can only parse `..`/`...`/`..=` for ranges \ (checked above)"), }; + let op_span = self.span; // Parse range let span = lo.to(self.prev_span); let begin = self.mk_expr(span, ExprKind::Path(qself, path), ThinVec::new()); self.bump(); let end = self.parse_pat_range_end()?; - pat = PatKind::Range(begin, end, end_kind); + let op = Spanned { span: op_span, node: end_kind }; + pat = PatKind::Range(begin, end, op); } token::OpenDelim(token::Brace) => { if qself.is_some() { @@ -4065,17 +4067,22 @@ impl<'a> Parser<'a> { // Try to parse everything else as literal with optional minus match self.parse_literal_maybe_minus() { Ok(begin) => { - if self.eat(&token::DotDotDot) { + let op_span = self.span; + if self.check(&token::DotDot) || self.check(&token::DotDotEq) || + self.check(&token::DotDotDot) { + let end_kind = if self.eat(&token::DotDotDot) { + RangeEnd::Included(RangeSyntax::DotDotDot) + } else if self.eat(&token::DotDotEq) { + RangeEnd::Included(RangeSyntax::DotDotEq) + } else if self.eat(&token::DotDot) { + RangeEnd::Excluded + } else { + panic!("impossible case: we already matched \ + on a range-operator token") + }; let end = self.parse_pat_range_end()?; - pat = PatKind::Range(begin, end, - RangeEnd::Included(RangeSyntax::DotDotDot)); - } else if self.eat(&token::DotDotEq) { - let end = self.parse_pat_range_end()?; - pat = PatKind::Range(begin, end, - RangeEnd::Included(RangeSyntax::DotDotEq)); - } else if self.eat(&token::DotDot) { - let end = self.parse_pat_range_end()?; - pat = PatKind::Range(begin, end, RangeEnd::Excluded); + let op = Spanned { span: op_span, node: end_kind }; + pat = PatKind::Range(begin, end, op); } else { pat = PatKind::Lit(begin); } @@ -4096,7 +4103,9 @@ impl<'a> Parser<'a> { if !allow_range_pat { match pat.node { - PatKind::Range(_, _, RangeEnd::Included(RangeSyntax::DotDotDot)) => {} + PatKind::Range( + _, _, Spanned { node: RangeEnd::Included(RangeSyntax::DotDotDot), .. } + ) => {}, PatKind::Range(..) => { let mut err = self.struct_span_err( pat.span, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 70c4324a056..3359225e159 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -16,7 +16,7 @@ use ast::{SelfKind, GenericBound, TraitBoundModifier}; use ast::{Attribute, MacDelimiter, GenericArg}; use util::parser::{self, AssocOp, Fixity}; use attr; -use codemap::{self, CodeMap}; +use codemap::{self, CodeMap, Spanned}; use syntax_pos::{self, BytePos}; use syntax_pos::hygiene::{Mark, SyntaxContext}; use parse::token::{self, BinOpToken, Token}; @@ -2624,7 +2624,7 @@ impl<'a> State<'a> { self.print_pat(inner)?; } PatKind::Lit(ref e) => self.print_expr(&**e)?, - PatKind::Range(ref begin, ref end, ref end_kind) => { + PatKind::Range(ref begin, ref end, Spanned { node: ref end_kind, .. }) => { self.print_expr(begin)?; self.s.space()?; match *end_kind { |
