Make rustc_parse_format compile on stable
This allows it to be used by lightweight formatting systems and may allow it to be used by rust-analyzer.
This commit is contained in:
parent
683c582c1e
commit
d33140d2dc
9 changed files with 231 additions and 191 deletions
|
@ -242,7 +242,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
fn resolve_name_inplace(&self, p: &mut parse::Piece<'_>) {
|
||||
// NOTE: the `unwrap_or` branch is needed in case of invalid format
|
||||
// arguments, e.g., `format_args!("{foo}")`.
|
||||
let lookup = |s: Symbol| *self.names.get(&s).unwrap_or(&0);
|
||||
let lookup = |s: &str| *self.names.get(&Symbol::intern(s)).unwrap_or(&0);
|
||||
|
||||
match *p {
|
||||
parse::String(_) => {}
|
||||
|
@ -276,7 +276,9 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
// it's written second, so it should come after width/precision.
|
||||
let pos = match arg.position {
|
||||
parse::ArgumentIs(i) | parse::ArgumentImplicitlyIs(i) => Exact(i),
|
||||
parse::ArgumentNamed(s, span) => Named(s, span),
|
||||
parse::ArgumentNamed(s, span) => {
|
||||
Named(Symbol::intern(s), InnerSpan::new(span.start, span.end))
|
||||
}
|
||||
};
|
||||
|
||||
let ty = Placeholder(match arg.format.ty {
|
||||
|
@ -291,7 +293,10 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
"X" => "UpperHex",
|
||||
_ => {
|
||||
let fmtsp = self.fmtsp;
|
||||
let sp = arg.format.ty_span.map(|sp| fmtsp.from_inner(sp));
|
||||
let sp = arg
|
||||
.format
|
||||
.ty_span
|
||||
.map(|sp| fmtsp.from_inner(InnerSpan::new(sp.start, sp.end)));
|
||||
let mut err = self.ecx.struct_span_err(
|
||||
sp.unwrap_or(fmtsp),
|
||||
&format!("unknown format trait `{}`", arg.format.ty),
|
||||
|
@ -340,14 +345,17 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
fn verify_count(&mut self, c: parse::Count) {
|
||||
fn verify_count(&mut self, c: parse::Count<'_>) {
|
||||
match c {
|
||||
parse::CountImplied | parse::CountIs(..) => {}
|
||||
parse::CountIsParam(i) => {
|
||||
self.verify_arg_type(Exact(i), Count);
|
||||
}
|
||||
parse::CountIsName(s, span) => {
|
||||
self.verify_arg_type(Named(s, span), Count);
|
||||
self.verify_arg_type(
|
||||
Named(Symbol::intern(s), InnerSpan::new(span.start, span.end)),
|
||||
Count,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -425,7 +433,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
|
||||
for fmt in &self.arg_with_formatting {
|
||||
if let Some(span) = fmt.precision_span {
|
||||
let span = self.fmtsp.from_inner(span);
|
||||
let span = self.fmtsp.from_inner(InnerSpan::new(span.start, span.end));
|
||||
match fmt.precision {
|
||||
parse::CountIsParam(pos) if pos > self.num_args() => {
|
||||
e.span_label(
|
||||
|
@ -471,7 +479,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
}
|
||||
}
|
||||
if let Some(span) = fmt.width_span {
|
||||
let span = self.fmtsp.from_inner(span);
|
||||
let span = self.fmtsp.from_inner(InnerSpan::new(span.start, span.end));
|
||||
match fmt.width {
|
||||
parse::CountIsParam(pos) if pos > self.num_args() => {
|
||||
e.span_label(
|
||||
|
@ -610,7 +618,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
ecx.std_path(&[sym::fmt, sym::rt, sym::v1, s])
|
||||
}
|
||||
|
||||
fn build_count(&self, c: parse::Count) -> P<ast::Expr> {
|
||||
fn build_count(&self, c: parse::Count<'_>) -> P<ast::Expr> {
|
||||
let sp = self.macsp;
|
||||
let count = |c, arg| {
|
||||
let mut path = Context::rtpath(self.ecx, sym::Count);
|
||||
|
@ -1033,7 +1041,7 @@ pub fn expand_preparsed_format_args(
|
|||
if !parser.errors.is_empty() {
|
||||
let err = parser.errors.remove(0);
|
||||
let sp = if efmt_kind_is_lit {
|
||||
fmt_span.from_inner(err.span)
|
||||
fmt_span.from_inner(InnerSpan::new(err.span.start, err.span.end))
|
||||
} else {
|
||||
// The format string could be another macro invocation, e.g.:
|
||||
// format!(concat!("abc", "{}"), 4);
|
||||
|
@ -1052,14 +1060,18 @@ pub fn expand_preparsed_format_args(
|
|||
}
|
||||
if let Some((label, span)) = err.secondary_label {
|
||||
if efmt_kind_is_lit {
|
||||
e.span_label(fmt_span.from_inner(span), label);
|
||||
e.span_label(fmt_span.from_inner(InnerSpan::new(span.start, span.end)), label);
|
||||
}
|
||||
}
|
||||
e.emit();
|
||||
return DummyResult::raw_expr(sp, true);
|
||||
}
|
||||
|
||||
let arg_spans = parser.arg_places.iter().map(|span| fmt_span.from_inner(*span)).collect();
|
||||
let arg_spans = parser
|
||||
.arg_places
|
||||
.iter()
|
||||
.map(|span| fmt_span.from_inner(InnerSpan::new(span.start, span.end)))
|
||||
.collect();
|
||||
|
||||
let named_pos: FxHashSet<usize> = names.values().cloned().collect();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue