1
Fork 0

Rollup merge of #56820 - ljedrz:format_tweaks, r=alexcrichton

format-related tweaks

- remove an unreachable condition
- inline one-liners related to `parse_expr` (called in succession)
- refactor `report_invalid_references`
- refactor `verify_arg_type`
- minor stylistic improvements
This commit is contained in:
Pietro Albini 2018-12-19 11:47:09 +01:00 committed by GitHub
commit 29aa466508
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 81 deletions

View file

@ -3062,6 +3062,7 @@ impl<'a> Parser<'a> {
/// ///
/// This parses an expression accounting for associativity and precedence of the operators in /// This parses an expression accounting for associativity and precedence of the operators in
/// the expression. /// the expression.
#[inline]
fn parse_assoc_expr(&mut self, fn parse_assoc_expr(&mut self,
already_parsed_attrs: Option<ThinVec<Attribute>>) already_parsed_attrs: Option<ThinVec<Attribute>>)
-> PResult<'a, P<Expr>> { -> PResult<'a, P<Expr>> {
@ -3722,6 +3723,7 @@ impl<'a> Parser<'a> {
} }
/// Parse an expression /// Parse an expression
#[inline]
pub fn parse_expr(&mut self) -> PResult<'a, P<Expr>> { pub fn parse_expr(&mut self) -> PResult<'a, P<Expr>> {
self.parse_expr_res(Restrictions::empty(), None) self.parse_expr_res(Restrictions::empty(), None)
} }
@ -3741,6 +3743,7 @@ impl<'a> Parser<'a> {
} }
/// Parse an expression, subject to the given restrictions /// Parse an expression, subject to the given restrictions
#[inline]
fn parse_expr_res(&mut self, r: Restrictions, fn parse_expr_res(&mut self, r: Restrictions,
already_parsed_attrs: Option<ThinVec<Attribute>>) already_parsed_attrs: Option<ThinVec<Attribute>>)
-> PResult<'a, P<Expr>> { -> PResult<'a, P<Expr>> {

View file

@ -158,28 +158,15 @@ fn parse_args(ecx: &mut ExtCtxt,
} // accept trailing commas } // accept trailing commas
if named || (p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq)) { if named || (p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq)) {
named = true; named = true;
let ident = match p.token { let ident = if let token::Ident(i, _) = p.token {
token::Ident(i, _) => { p.bump();
p.bump(); i
i } else {
} ecx.span_err(
_ if named => { p.span,
ecx.span_err( "expected ident, positional arguments cannot follow named arguments",
p.span, );
"expected ident, positional arguments cannot follow named arguments", return None;
);
return None;
}
_ => {
ecx.span_err(
p.span,
&format!(
"expected ident for named argument, found `{}`",
p.this_token_to_string()
),
);
return None;
}
}; };
let name: &str = &ident.as_str(); let name: &str = &ident.as_str();
@ -286,11 +273,11 @@ impl<'a, 'b> Context<'a, 'b> {
} else { } else {
MultiSpan::from_span(self.fmtsp) MultiSpan::from_span(self.fmtsp)
}; };
let mut refs: Vec<_> = self let refs_len = self.invalid_refs.len();
let mut refs = self
.invalid_refs .invalid_refs
.iter() .iter()
.map(|(r, pos)| (r.to_string(), self.arg_spans.get(*pos))) .map(|(r, pos)| (r.to_string(), self.arg_spans.get(*pos)));
.collect();
if self.names.is_empty() && !numbered_position_args { if self.names.is_empty() && !numbered_position_args {
e = self.ecx.mut_span_err( e = self.ecx.mut_span_err(
@ -303,28 +290,24 @@ impl<'a, 'b> Context<'a, 'b> {
), ),
); );
} else { } else {
let (arg_list, mut sp) = match refs.len() { let (arg_list, mut sp) = if refs_len == 1 {
1 => { let (reg, pos) = refs.next().unwrap();
let (reg, pos) = refs.pop().unwrap(); (
( format!("argument {}", reg),
format!("argument {}", reg), MultiSpan::from_span(*pos.unwrap_or(&self.fmtsp)),
MultiSpan::from_span(*pos.unwrap_or(&self.fmtsp)), )
) } else {
} let (mut refs, spans): (Vec<_>, Vec<_>) = refs.unzip();
_ => { let pos = MultiSpan::from_spans(spans.into_iter().map(|s| *s.unwrap()).collect());
let pos = let reg = refs.pop().unwrap();
MultiSpan::from_spans(refs.iter().map(|(_, p)| *p.unwrap()).collect()); (
let mut refs: Vec<String> = refs.iter().map(|(s, _)| s.to_owned()).collect(); format!(
let reg = refs.pop().unwrap(); "arguments {head} and {tail}",
( head = refs.join(", "),
format!( tail = reg,
"arguments {head} and {tail}", ),
tail = reg, pos,
head = refs.join(", ") )
),
pos,
)
}
}; };
if !self.is_literal { if !self.is_literal {
sp = MultiSpan::from_span(self.fmtsp); sp = MultiSpan::from_span(self.fmtsp);
@ -353,33 +336,30 @@ impl<'a, 'b> Context<'a, 'b> {
Placeholder(_) => { Placeholder(_) => {
// record every (position, type) combination only once // record every (position, type) combination only once
let ref mut seen_ty = self.arg_unique_types[arg]; let ref mut seen_ty = self.arg_unique_types[arg];
let i = match seen_ty.iter().position(|x| *x == ty) { let i = seen_ty.iter().position(|x| *x == ty).unwrap_or_else(|| {
Some(i) => i, let i = seen_ty.len();
None => { seen_ty.push(ty);
let i = seen_ty.len(); i
seen_ty.push(ty); });
i
}
};
self.arg_types[arg].push(i); self.arg_types[arg].push(i);
} }
Count => { Count => {
match self.count_positions.entry(arg) { if let Entry::Vacant(e) = self.count_positions.entry(arg) {
Entry::Vacant(e) => { let i = self.count_positions_count;
let i = self.count_positions_count; e.insert(i);
e.insert(i); self.count_args.push(Exact(arg));
self.count_args.push(Exact(arg)); self.count_positions_count += 1;
self.count_positions_count += 1;
}
Entry::Occupied(_) => {}
} }
} }
} }
} }
Named(name) => { Named(name) => {
let idx = match self.names.get(&name) { match self.names.get(&name) {
Some(e) => *e, Some(idx) => {
// Treat as positional arg.
self.verify_arg_type(Exact(*idx), ty)
}
None => { None => {
let msg = format!("there is no argument named `{}`", name); let msg = format!("there is no argument named `{}`", name);
let sp = if self.is_literal { let sp = if self.is_literal {
@ -389,11 +369,8 @@ impl<'a, 'b> Context<'a, 'b> {
}; };
let mut err = self.ecx.struct_span_err(sp, &msg[..]); let mut err = self.ecx.struct_span_err(sp, &msg[..]);
err.emit(); err.emit();
return;
} }
}; }
// Treat as positional arg.
self.verify_arg_type(Exact(idx), ty)
} }
} }
} }
@ -436,12 +413,10 @@ impl<'a, 'b> Context<'a, 'b> {
parse::CountIs(i) => count("Is", Some(self.ecx.expr_usize(sp, i))), parse::CountIs(i) => count("Is", Some(self.ecx.expr_usize(sp, i))),
parse::CountIsParam(i) => { parse::CountIsParam(i) => {
// This needs mapping too, as `i` is referring to a macro // This needs mapping too, as `i` is referring to a macro
// argument. // argument. If `i` is not found in `count_positions` then
let i = match self.count_positions.get(&i) { // the error had already been emitted elsewhere.
Some(&i) => i, let i = self.count_positions.get(&i).cloned().unwrap_or(0)
None => 0, // error already emitted elsewhere + self.count_args_index_offset;
};
let i = i + self.count_args_index_offset;
count("Param", Some(self.ecx.expr_usize(sp, i))) count("Param", Some(self.ecx.expr_usize(sp, i)))
} }
parse::CountImplied => count("Implied", None), parse::CountImplied => count("Implied", None),
@ -526,10 +501,7 @@ impl<'a, 'b> Context<'a, 'b> {
}, },
}; };
let fill = match arg.format.fill { let fill = arg.format.fill.unwrap_or(' ');
Some(c) => c,
None => ' ',
};
if *arg != simple_arg || fill != ' ' { if *arg != simple_arg || fill != ' ' {
self.all_pieces_simple = false; self.all_pieces_simple = false;
@ -828,8 +800,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
if !parser.errors.is_empty() { if !parser.errors.is_empty() {
let err = parser.errors.remove(0); let err = parser.errors.remove(0);
let sp = fmt.span.from_inner_byte_pos(err.start, err.end); let sp = fmt.span.from_inner_byte_pos(err.start, err.end);
let mut e = ecx.struct_span_err(sp, &format!("invalid format string: {}", let mut e = ecx.struct_span_err(sp, &format!("invalid format string: {}", err.description));
err.description));
e.span_label(sp, err.label + " in format string"); e.span_label(sp, err.label + " in format string");
if let Some(note) = err.note { if let Some(note) = err.note {
e.note(&note); e.note(&note);