1
Fork 0

libsyntax: Tighten up expressions in patterns to only allow identifiers or literals (possibly with a minus).

This had very minimal fallout.
This commit is contained in:
Patrick Walton 2013-05-10 18:19:58 -07:00
parent 5d3559e645
commit db0693ac8d
3 changed files with 53 additions and 26 deletions

View file

@ -486,10 +486,10 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
} }
} }
let (start, accum_positive) = match buf[0] { let (start, accum_positive) = match buf[0] as char {
'-' as u8 if !negative => return None, '-' if !negative => return None,
'-' as u8 => (1u, false), '-' => (1u, false),
'+' as u8 => (1u, true), '+' => (1u, true),
_ => (0u, true) _ => (0u, true)
}; };

View file

@ -257,12 +257,12 @@ pub mod ct {
let mut flags = ~[]; let mut flags = ~[];
while i < lim { while i < lim {
let f = match s[i] { let f = match s[i] as char {
'-' as u8 => FlagLeftJustify, '-' => FlagLeftJustify,
'0' as u8 => FlagLeftZeroPad, '0' => FlagLeftZeroPad,
' ' as u8 => FlagSpaceForSign, ' ' => FlagSpaceForSign,
'+' as u8 => FlagSignAlways, '+' => FlagSignAlways,
'#' as u8 => FlagAlternate, '#' => FlagAlternate,
_ => break _ => break
}; };
@ -313,18 +313,18 @@ pub mod ct {
// FIXME (#2249): Do we really want two signed types here? // FIXME (#2249): Do we really want two signed types here?
// How important is it to be printf compatible? // How important is it to be printf compatible?
let t = match s[i] { let t = match s[i] as char {
'b' as u8 => TyBool, 'b' => TyBool,
's' as u8 => TyStr, 's' => TyStr,
'c' as u8 => TyChar, 'c' => TyChar,
'd' as u8 | 'i' as u8 => TyInt(Signed), 'd' | 'i' => TyInt(Signed),
'u' as u8 => TyInt(Unsigned), 'u' => TyInt(Unsigned),
'x' as u8 => TyHex(CaseLower), 'x' => TyHex(CaseLower),
'X' as u8 => TyHex(CaseUpper), 'X' => TyHex(CaseUpper),
't' as u8 => TyBits, 't' => TyBits,
'o' as u8 => TyOctal, 'o' => TyOctal,
'f' as u8 => TyFloat, 'f' => TyFloat,
'?' as u8 => TyPoly, '?' => TyPoly,
_ => err(~"unknown type in conversion: " + s.substr(i, 1)) _ => err(~"unknown type in conversion: " + s.substr(i, 1))
}; };

View file

@ -915,6 +915,24 @@ pub impl Parser {
codemap::spanned { node: lit, span: mk_sp(lo, self.last_span.hi) } codemap::spanned { node: lit, span: mk_sp(lo, self.last_span.hi) }
} }
// matches '-' lit | lit
fn parse_literal_maybe_minus(&self) -> @expr {
let minus_lo = self.span.lo;
let minus_present = self.eat(&token::BINOP(token::MINUS));
let lo = self.span.lo;
let literal = @self.parse_lit();
let hi = self.span.hi;
let expr = self.mk_expr(lo, hi, expr_lit(literal));
if minus_present {
let minus_hi = self.span.hi;
self.mk_expr(minus_lo, minus_hi, expr_unary(neg, expr))
} else {
expr
}
}
// parse a path into a vector of idents, whether the path starts // parse a path into a vector of idents, whether the path starts
// with ::, and a span. // with ::, and a span.
fn parse_path(&self) -> (~[ast::ident],bool,span) { fn parse_path(&self) -> (~[ast::ident],bool,span) {
@ -2360,10 +2378,19 @@ pub impl Parser {
|| self.is_keyword(&~"true") || self.is_keyword(&~"true")
|| self.is_keyword(&~"false") || self.is_keyword(&~"false")
{ {
// parse an expression pattern or exp .. exp // Parse an expression pattern or exp .. exp.
let val = self.parse_expr_res(RESTRICT_NO_BAR_OP); //
// These expressions are limited to literals (possibly
// preceded by unary-minus) or identifiers.
let val = self.parse_literal_maybe_minus();
if self.eat(&token::DOTDOT) { if self.eat(&token::DOTDOT) {
let end = self.parse_expr_res(RESTRICT_NO_BAR_OP); let end = if is_ident_or_path(&tok) {
let path = self.parse_path_with_tps(true);
let hi = self.span.hi;
self.mk_expr(lo, hi, expr_path(path))
} else {
self.parse_literal_maybe_minus()
};
pat = pat_range(val, end); pat = pat_range(val, end);
} else { } else {
pat = pat_lit(val); pat = pat_lit(val);