use std::borrow::Cow;
use std::cell::Cell;
+use std::collections::BTreeMap;
use std::vec;
pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: hir::HirId) -> String {
impl PpAnn for hir::Crate<'_> {
fn nested(&self, state: &mut State<'_>, nested: Nested) {
match nested {
- Nested::Item(id) => state.print_item(self.item(id.id)),
+ Nested::Item(id) => state.print_item(self.item(id)),
Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
Nested::ForeignItem(id) => state.print_foreign_item(self.foreign_item(id)),
impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> {
fn nested(&self, state: &mut State<'_>, nested: Nested) {
match nested {
- Nested::Item(id) => state.print_item(self.item(id.id)),
+ Nested::Item(id) => state.print_item(self.item(id)),
Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
Nested::ForeignItem(id) => state.print_foreign_item(self.foreign_item(id)),
pub struct State<'a> {
pub s: pp::Printer,
comments: Option<Comments<'a>>,
+ attrs: &'a BTreeMap<hir::HirId, &'a [ast::Attribute]>,
ann: &'a (dyn PpAnn + 'a),
}
Node::Lifetime(a) => self.print_lifetime(&a),
Node::Visibility(a) => self.print_visibility(&a),
Node::GenericParam(_) => panic!("cannot print Node::GenericParam"),
- Node::Field(_) => panic!("cannot print StructField"),
+ Node::Field(_) => panic!("cannot print Node::Field"),
// These cases do not carry enough information in the
// `hir_map` to reconstruct their full structure for pretty
// printing.
input: String,
ann: &'a dyn PpAnn,
) -> String {
- let mut s = State::new_from_input(sm, filename, input, ann);
+ let mut s = State::new_from_input(sm, filename, input, &krate.attrs, ann);
// When printing the AST, we sometimes need to inject `#[no_std]` here.
// Since you can't compile the HIR, it's not necessary.
- s.print_mod(&krate.item.module, &krate.item.attrs);
+ s.print_mod(&krate.item.module, s.attrs(hir::CRATE_HIR_ID));
s.print_remaining_comments();
s.s.eof()
}
sm: &'a SourceMap,
filename: FileName,
input: String,
+ attrs: &'a BTreeMap<hir::HirId, &[ast::Attribute]>,
ann: &'a dyn PpAnn,
) -> State<'a> {
- State { s: pp::mk_printer(), comments: Some(Comments::new(sm, filename, input)), ann }
+ State {
+ s: pp::mk_printer(),
+ comments: Some(Comments::new(sm, filename, input)),
+ attrs,
+ ann,
+ }
+ }
+
+ fn attrs(&self, id: hir::HirId) -> &'a [ast::Attribute] {
+ self.attrs.get(&id).map_or(&[], |la| *la)
}
}
where
F: FnOnce(&mut State<'_>),
{
- let mut printer = State { s: pp::mk_printer(), comments: None, ann };
+ let mut printer =
+ State { s: pp::mk_printer(), comments: None, attrs: &BTreeMap::default(), ann };
f(&mut printer);
printer.s.eof()
}
&f.decl,
None,
&f.generic_params,
- &f.param_names[..],
+ f.param_names,
);
}
hir::TyKind::OpaqueDef(..) => self.s.word("/*impl Trait*/"),
hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
- hir::TyKind::TraitObject(bounds, ref lifetime) => {
+ hir::TyKind::TraitObject(bounds, ref lifetime, syntax) => {
+ if syntax == ast::TraitObjectSyntax::Dyn {
+ self.word_space("dyn");
+ }
let mut first = true;
for bound in bounds {
if first {
pub fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
self.hardbreak_if_not_bol();
self.maybe_print_comment(item.span.lo());
- self.print_outer_attributes(&item.attrs);
+ self.print_outer_attributes(self.attrs(item.hir_id()));
match item.kind {
hir::ForeignItemKind::Fn(ref decl, ref arg_names, ref generics) => {
self.head("");
pub fn print_item(&mut self, item: &hir::Item<'_>) {
self.hardbreak_if_not_bol();
self.maybe_print_comment(item.span.lo());
- self.print_outer_attributes(&item.attrs);
+ let attrs = self.attrs(item.hir_id());
+ self.print_outer_attributes(attrs);
self.ann.pre(self, AnnNode::Item(item));
match item.kind {
hir::ItemKind::ExternCrate(orig_name) => {
self.print_ident(item.ident);
self.nbsp();
self.bopen();
- self.print_mod(_mod, &item.attrs);
+ self.print_mod(_mod, attrs);
self.bclose(item.span);
}
hir::ItemKind::ForeignMod { abi, items } => {
self.head("extern");
self.word_nbsp(abi.to_string());
self.bopen();
- self.print_inner_attributes(item.attrs);
+ self.print_inner_attributes(self.attrs(item.hir_id()));
for item in items {
self.ann.nested(self, Nested::ForeignItem(item.id));
}
self.s.space();
self.bopen();
- self.print_inner_attributes(&item.attrs);
+ self.print_inner_attributes(attrs);
for impl_item in items {
self.ann.nested(self, Nested::ImplItem(impl_item.id));
}
for v in variants {
self.space_if_not_bol();
self.maybe_print_comment(v.span.lo());
- self.print_outer_attributes(&v.attrs);
+ self.print_outer_attributes(self.attrs(v.id));
self.ibox(INDENT_UNIT);
self.print_variant(v);
self.s.word(",");
self.popen();
self.commasep(Inconsistent, struct_def.fields(), |s, field| {
s.maybe_print_comment(field.span.lo());
- s.print_outer_attributes(&field.attrs);
+ s.print_outer_attributes(s.attrs(field.hir_id));
s.print_visibility(&field.vis);
s.print_type(&field.ty)
});
for field in struct_def.fields() {
self.hardbreak_if_not_bol();
self.maybe_print_comment(field.span.lo());
- self.print_outer_attributes(&field.attrs);
+ self.print_outer_attributes(self.attrs(field.hir_id));
self.print_visibility(&field.vis);
self.print_ident(field.ident);
self.word_nbsp(":");
}
pub fn print_trait_item(&mut self, ti: &hir::TraitItem<'_>) {
- self.ann.pre(self, AnnNode::SubItem(ti.hir_id));
+ self.ann.pre(self, AnnNode::SubItem(ti.hir_id()));
self.hardbreak_if_not_bol();
self.maybe_print_comment(ti.span.lo());
- self.print_outer_attributes(&ti.attrs);
+ self.print_outer_attributes(self.attrs(ti.hir_id()));
match ti.kind {
hir::TraitItemKind::Const(ref ty, default) => {
let vis =
);
}
}
- self.ann.post(self, AnnNode::SubItem(ti.hir_id))
+ self.ann.post(self, AnnNode::SubItem(ti.hir_id()))
}
pub fn print_impl_item(&mut self, ii: &hir::ImplItem<'_>) {
- self.ann.pre(self, AnnNode::SubItem(ii.hir_id));
+ self.ann.pre(self, AnnNode::SubItem(ii.hir_id()));
self.hardbreak_if_not_bol();
self.maybe_print_comment(ii.span.lo());
- self.print_outer_attributes(&ii.attrs);
+ self.print_outer_attributes(self.attrs(ii.hir_id()));
self.print_defaultness(ii.defaultness);
match ii.kind {
self.print_associated_type(ii.ident, &ii.generics, None, Some(ty));
}
}
- self.ann.post(self, AnnNode::SubItem(ii.hir_id))
+ self.ann.post(self, AnnNode::SubItem(ii.hir_id()))
}
pub fn print_local(&mut self, init: Option<&hir::Expr<'_>>, decl: impl Fn(&mut Self)) {
fn print_expr_struct(
&mut self,
qpath: &hir::QPath<'_>,
- fields: &[hir::Field<'_>],
+ fields: &[hir::ExprField<'_>],
wth: &Option<&hir::Expr<'_>>,
) {
self.print_qpath(qpath, true);
self.s.word("{");
self.commasep_cmnt(
Consistent,
- &fields[..],
+ fields,
|s, field| {
s.ibox(INDENT_UNIT);
if !field.is_shorthand {
pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
self.maybe_print_comment(expr.span.lo());
- self.print_outer_attributes(&expr.attrs);
+ self.print_outer_attributes(self.attrs(expr.hir_id));
self.ibox(INDENT_UNIT);
self.ann.pre(self, AnnNode::Expr(expr));
match expr.kind {
}
pub fn print_param(&mut self, arg: &hir::Param<'_>) {
- self.print_outer_attributes(&arg.attrs);
+ self.print_outer_attributes(self.attrs(arg.hir_id));
self.print_pat(&arg.pat);
}
pub fn print_arm(&mut self, arm: &hir::Arm<'_>) {
// I have no idea why this check is necessary, but here it
// is :(
- if arm.attrs.is_empty() {
+ if self.attrs(arm.hir_id).is_empty() {
self.s.space();
}
self.cbox(INDENT_UNIT);
self.ann.pre(self, AnnNode::Arm(arm));
self.ibox(0);
- self.print_outer_attributes(&arm.attrs);
+ self.print_outer_attributes(&self.attrs(arm.hir_id));
self.print_pat(&arm.pat);
self.s.space();
if let Some(ref g) = arm.guard {